Add caps unref to avoid mem leak
[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 <string.h>
41
42 #include "rtsp-media-factory-wfd.h"
43 #include "gstwfdmessage.h"
44 #include "rtsp-media-ext.h"
45
46 #define GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE(obj)  \
47        (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTSP_MEDIA_FACTORY_WFD, GstRTSPMediaFactoryWFDPrivate))
48
49 #define GST_RTSP_MEDIA_FACTORY_WFD_GET_LOCK(f)       (&(GST_RTSP_MEDIA_FACTORY_WFD_CAST(f)->priv->lock))
50 #define GST_RTSP_MEDIA_FACTORY_WFD_LOCK(f)           (g_mutex_lock(GST_RTSP_MEDIA_FACTORY_WFD_GET_LOCK(f)))
51 #define GST_RTSP_MEDIA_FACTORY_WFD_UNLOCK(f)         (g_mutex_unlock(GST_RTSP_MEDIA_FACTORY_WFD_GET_LOCK(f)))
52
53 typedef struct _GstRTPSMediaWFDTypeFindResult GstRTPSMediaWFDTypeFindResult;
54
55 struct _GstRTPSMediaWFDTypeFindResult{
56   gint h264_found;
57   gint aac_found;
58   gint ac3_found;
59   GstElementFactory *demux_fact;
60   GstElementFactory *src_fact;
61 };
62
63 typedef struct _GstRTSPMediaWFDDirectPipelineData GstRTSPMediaWFDDirectPipelineData;
64
65 struct _GstRTSPMediaWFDDirectPipelineData {
66   GstBin *pipeline;
67   GstElement *ap;
68   GstElement *vp;
69   GstElement *aq;
70   GstElement *vq;
71   GstElement *tsmux;
72   GstElement *mux_fs;
73   gchar *uri;
74 };
75
76
77 struct _GstRTSPMediaFactoryWFDPrivate
78 {
79   GMutex lock;
80   GstRTSPPermissions *permissions;
81   gchar *launch;
82   gboolean shared;
83   GstRTSPLowerTrans protocols;
84   guint buffer_size;
85   guint mtu_size;
86
87   guint8 videosrc_type;
88   guint8 video_codec;
89   gchar *video_encoder;
90   guint video_bitrate;
91   guint video_width;
92   guint video_height;
93   guint video_framerate;
94   guint video_enc_skip_inbuf_value;
95   GstElement *video_queue;
96   GstBin *video_srcbin;
97
98   GstElement *venc;
99   guint decide_udp_bitrate[21];
100   guint min_udp_bitrate;
101   guint max_udp_bitrate;
102   gboolean decided_udp_bitrate;
103
104   gchar *audio_device;
105   gchar *audio_encoder_aac;
106   gchar *audio_encoder_ac3;
107   guint8 audio_codec;
108   guint64 audio_latency_time;
109   guint64 audio_buffer_time;
110   gboolean audio_do_timestamp;
111   guint8 audio_channels;
112   guint8 audio_freq;
113   guint8 audio_bitrate;
114   GstElement *audio_queue;
115   GstBin *audio_srcbin;
116
117   GMutex direct_lock;
118   GCond direct_cond;
119   GType decodebin_type;
120   GstBin *discover_pipeline;
121   GstRTPSMediaWFDTypeFindResult res;
122   GstRTSPMediaWFDDirectPipelineData *direct_pipe;
123   GstBin *stream_bin;
124   GstElement *mux;
125   GstElement *mux_queue;
126   GstElement *pay;
127   GstElement *stub_fs;
128   GMainLoop *discover_loop;
129
130   guint64 video_resolution_supported;
131
132   gboolean dump_ts;
133 };
134
135 #define DEFAULT_LAUNCH          NULL
136 #define DEFAULT_SHARED          FALSE
137 #define DEFAULT_PROTOCOLS       GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_UDP_MCAST | \
138                                         GST_RTSP_LOWER_TRANS_TCP
139 #define DEFAULT_BUFFER_SIZE     0x80000
140
141 enum
142 {
143   PROP_0,
144   PROP_LAUNCH,
145   PROP_SHARED,
146   PROP_SUSPEND_MODE,
147   PROP_EOS_SHUTDOWN,
148   PROP_PROTOCOLS,
149   PROP_BUFFER_SIZE,
150   PROP_LAST
151 };
152
153 enum
154 {
155   SIGNAL_MEDIA_CONSTRUCTED,
156   SIGNAL_MEDIA_CONFIGURE,
157   SIGNAL_DIRECT_STREAMING_END,
158   SIGNAL_LAST
159 };
160
161 GST_DEBUG_CATEGORY_STATIC (rtsp_media_wfd_debug);
162 #define GST_CAT_DEFAULT rtsp_media_wfd_debug
163
164 static guint gst_rtsp_media_factory_wfd_signals[SIGNAL_LAST] = { 0 };
165
166 static void gst_rtsp_media_factory_wfd_get_property (GObject * object,
167     guint propid, GValue * value, GParamSpec * pspec);
168 static void gst_rtsp_media_factory_wfd_set_property (GObject * object,
169     guint propid, const GValue * value, GParamSpec * pspec);
170
171 static void gst_rtsp_media_factory_wfd_finalize (GObject * obj);
172
173
174 static GstElement *rtsp_media_factory_wfd_create_element (GstRTSPMediaFactory *
175     factory, const GstRTSPUrl * url);
176 static GstRTSPMedia *rtsp_media_factory_wfd_construct (GstRTSPMediaFactory *
177     factory, const GstRTSPUrl * url);
178
179 static void _config_bitrate (GstRTSPMediaFactoryWFD * factory);
180
181 G_DEFINE_TYPE (GstRTSPMediaFactoryWFD, gst_rtsp_media_factory_wfd,
182     GST_TYPE_RTSP_MEDIA_FACTORY);
183
184 static void
185 gst_rtsp_media_factory_wfd_class_init (GstRTSPMediaFactoryWFDClass * klass)
186 {
187   GObjectClass *gobject_class;
188   GstRTSPMediaFactoryClass *factory_class;
189
190   g_type_class_add_private (klass, sizeof (GstRTSPMediaFactoryWFDPrivate));
191
192   gobject_class = G_OBJECT_CLASS (klass);
193   factory_class = GST_RTSP_MEDIA_FACTORY_CLASS (klass);
194
195   gobject_class->get_property = gst_rtsp_media_factory_wfd_get_property;
196   gobject_class->set_property = gst_rtsp_media_factory_wfd_set_property;
197   gobject_class->finalize = gst_rtsp_media_factory_wfd_finalize;
198
199   gst_rtsp_media_factory_wfd_signals[SIGNAL_DIRECT_STREAMING_END] =
200       g_signal_new ("direct-stream-end", G_TYPE_FROM_CLASS (klass),
201       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPMediaFactoryWFDClass,
202           direct_stream_end), NULL, NULL, g_cclosure_marshal_generic,
203       G_TYPE_NONE, 0, G_TYPE_NONE);
204
205   factory_class->construct = rtsp_media_factory_wfd_construct;
206   factory_class->create_element = rtsp_media_factory_wfd_create_element;
207
208   GST_DEBUG_CATEGORY_INIT (rtsp_media_wfd_debug, "rtspmediafactorywfd", 0,
209       "GstRTSPMediaFactoryWFD");
210 }
211
212 void
213 gst_rtsp_media_factory_wfd_set (GstRTSPMediaFactoryWFD * factory,
214     guint8 videosrc_type, gchar * audio_device, guint64 audio_latency_time,
215     guint64 audio_buffer_time, gboolean audio_do_timestamp, guint mtu_size)
216 {
217   GstRTSPMediaFactoryWFDPrivate *priv =
218       GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE (factory);
219   factory->priv = priv;
220
221   priv->videosrc_type = videosrc_type;
222   priv->audio_device = audio_device;
223   priv->audio_latency_time = audio_latency_time;
224   priv->audio_buffer_time = audio_buffer_time;
225   priv->audio_do_timestamp = audio_do_timestamp;
226   priv->mtu_size = mtu_size;
227 }
228
229 void
230 gst_rtsp_media_factory_wfd_set_encoders (GstRTSPMediaFactoryWFD * factory,
231     gchar * video_encoder, gchar * audio_encoder_aac, gchar * audio_encoder_ac3)
232 {
233   GstRTSPMediaFactoryWFDPrivate *priv =
234       GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE (factory);
235   factory->priv = priv;
236
237   priv->video_encoder = video_encoder;
238   priv->audio_encoder_aac = audio_encoder_aac;
239   priv->audio_encoder_ac3 = audio_encoder_ac3;
240 }
241
242 void
243 gst_rtsp_media_factory_wfd_set_dump_ts (GstRTSPMediaFactoryWFD * factory,
244     gboolean dump_ts)
245 {
246   GstRTSPMediaFactoryWFDPrivate *priv =
247       GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE (factory);
248   factory->priv = priv;
249
250   priv->dump_ts = dump_ts;
251 }
252
253 void
254 gst_rtsp_media_factory_wfd_set_negotiated_resolution (GstRTSPMediaFactory *
255     factory, guint32 width, guint32 height)
256 {
257   GstRTSPMediaFactoryWFD *factory_wfd = GST_RTSP_MEDIA_FACTORY_WFD (factory);
258   GstRTSPMediaFactoryWFDPrivate *priv = factory_wfd->priv;
259
260   priv->video_width = width;
261   priv->video_height = height;
262   _config_bitrate (factory_wfd);
263 }
264
265 void
266 gst_rtsp_media_factory_wfd_set_audio_codec (GstRTSPMediaFactory * factory,
267     guint audio_codec)
268 {
269   GstRTSPMediaFactoryWFD *factory_wfd = GST_RTSP_MEDIA_FACTORY_WFD (factory);
270   GstRTSPMediaFactoryWFDPrivate *priv = factory_wfd->priv;
271
272   priv->audio_codec = audio_codec;
273 }
274
275 void
276 gst_rtsp_media_factory_wfd_set_video_codec (GstRTSPMediaFactory * factory,
277     guint video_codec)
278 {
279   GstRTSPMediaFactoryWFD *factory_wfd = GST_RTSP_MEDIA_FACTORY_WFD (factory);
280   GstRTSPMediaFactoryWFDPrivate *priv = factory_wfd->priv;
281
282   priv->video_codec = video_codec;
283 }
284
285 static void
286 _config_bitrate (GstRTSPMediaFactoryWFD * factory)
287 {
288   GstRTSPMediaFactoryWFDPrivate *priv = factory->priv;
289
290   if (priv->decided_udp_bitrate) {
291     priv->video_bitrate = priv->decide_udp_bitrate[0];
292     priv->min_udp_bitrate = priv->decide_udp_bitrate[1];
293     priv->max_udp_bitrate = priv->decide_udp_bitrate[2];
294
295     if ((priv->video_width * priv->video_height) >= (1920 * 1080)) {
296       priv->video_bitrate = priv->decide_udp_bitrate[3];
297       priv->min_udp_bitrate = priv->decide_udp_bitrate[4];
298       priv->max_udp_bitrate = priv->decide_udp_bitrate[5];
299     } else if ((priv->video_width * priv->video_height) >= (1280 * 720)) {
300       priv->video_bitrate = priv->decide_udp_bitrate[6];
301       priv->min_udp_bitrate = priv->decide_udp_bitrate[7];
302       priv->max_udp_bitrate = priv->decide_udp_bitrate[8];
303     } else if ((priv->video_width * priv->video_height) >= (960 * 540)) {
304       priv->video_bitrate = priv->decide_udp_bitrate[9];
305       priv->min_udp_bitrate = priv->decide_udp_bitrate[10];
306       priv->max_udp_bitrate = priv->decide_udp_bitrate[11];
307     } else if ((priv->video_width * priv->video_height) >= (854 * 480)) {
308       priv->video_bitrate = priv->decide_udp_bitrate[12];
309       priv->min_udp_bitrate = priv->decide_udp_bitrate[13];
310       priv->max_udp_bitrate = priv->decide_udp_bitrate[14];
311     } else if ((priv->video_width * priv->video_height) >= (640 * 480)) {
312       priv->video_bitrate = priv->decide_udp_bitrate[15];
313       priv->min_udp_bitrate = priv->decide_udp_bitrate[16];
314       priv->max_udp_bitrate = priv->decide_udp_bitrate[17];
315     }
316   }
317 }
318
319 void
320 gst_rtsp_media_factory_wfd_set_venc_bitrate (GstRTSPMediaFactory * factory,
321     gint bitrate)
322 {
323   GstRTSPMediaFactoryWFD *factory_wfd = GST_RTSP_MEDIA_FACTORY_WFD (factory);
324   GstRTSPMediaFactoryWFDPrivate *priv = factory_wfd->priv;
325
326   g_object_set (priv->venc, "target-bitrate", bitrate, NULL);
327   priv->video_bitrate = (guint) bitrate;
328 }
329
330 void
331 gst_rtsp_media_factory_wfd_get_venc_bitrate (GstRTSPMediaFactory * factory,
332     gint * bitrate)
333 {
334   int cur_bitrate = 0;
335
336   GstRTSPMediaFactoryWFD *factory_wfd = GST_RTSP_MEDIA_FACTORY_WFD (factory);
337   GstRTSPMediaFactoryWFDPrivate *priv = factory_wfd->priv;
338
339   g_object_get (priv->venc, "target-bitrate", &cur_bitrate, NULL);
340
341   if (cur_bitrate == 0) {
342     *bitrate = priv->video_bitrate;
343   } else {
344     *bitrate = (gint) cur_bitrate;
345   }
346 }
347
348 void
349 gst_rtsp_media_factory_wfd_get_config_bitrate (GstRTSPMediaFactory * factory,
350     guint32 * min, guint32 * max)
351 {
352   GstRTSPMediaFactoryWFD *factory_wfd = GST_RTSP_MEDIA_FACTORY_WFD (factory);
353   GstRTSPMediaFactoryWFDPrivate *priv = factory_wfd->priv;
354
355   *min = priv->min_udp_bitrate;
356   *max = priv->max_udp_bitrate;
357 }
358
359 void
360 gst_rtsp_media_factory_wfd_set_config_bitrate (GstRTSPMediaFactoryWFD * factory,
361     guint * config_bitrate)
362 {
363   GstRTSPMediaFactoryWFDPrivate *priv = factory->priv;
364
365   gint idx = 0;
366   for (idx = 0; idx < 21; idx++) {
367     priv->decide_udp_bitrate[idx] = config_bitrate[idx];
368   }
369   priv->decided_udp_bitrate = TRUE;
370
371   _config_bitrate (factory);
372 }
373
374 static void
375 gst_rtsp_media_factory_wfd_init (GstRTSPMediaFactoryWFD * factory)
376 {
377   GstRTSPMediaFactoryWFDPrivate *priv =
378       GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE (factory);
379   factory->priv = priv;
380
381   priv->launch = g_strdup (DEFAULT_LAUNCH);
382   priv->shared = DEFAULT_SHARED;
383   priv->protocols = DEFAULT_PROTOCOLS;
384   priv->buffer_size = DEFAULT_BUFFER_SIZE;
385
386   //priv->videosrc_type = GST_WFD_VSRC_XIMAGESRC;
387   //priv->videosrc_type = GST_WFD_VSRC_XVIMAGESRC;
388   //priv->videosrc_type = GST_WFD_VSRC_CAMERASRC;
389   priv->videosrc_type = GST_WFD_VSRC_VIDEOTESTSRC;
390   priv->video_codec = GST_WFD_VIDEO_H264;
391   priv->video_encoder = g_strdup ("omxh264enc");
392   priv->video_bitrate = 200000;
393   priv->video_width = 640;
394   priv->video_height = 480;
395   priv->video_framerate = 30;
396   priv->video_enc_skip_inbuf_value = 5;
397   priv->video_srcbin = NULL;
398   priv->min_udp_bitrate = 938861;
399   priv->max_udp_bitrate = 1572864;
400   priv->decided_udp_bitrate = FALSE;
401
402   priv->audio_device = g_strdup ("alsa_output.1.analog-stereo.monitor");
403   priv->audio_codec = GST_WFD_AUDIO_AAC;
404   priv->audio_encoder_aac = g_strdup ("avenc_aac");
405   priv->audio_encoder_ac3 = g_strdup ("avenc_ac3");
406   priv->audio_latency_time = 10000;
407   priv->audio_buffer_time = 200000;
408   priv->audio_do_timestamp = FALSE;
409   priv->audio_channels = GST_WFD_CHANNEL_2;
410   priv->audio_freq = GST_WFD_FREQ_48000;
411   priv->audio_srcbin = NULL;
412
413   g_mutex_init (&priv->direct_lock);
414   g_cond_init (&priv->direct_cond);
415
416   priv->discover_pipeline = NULL;
417   priv->direct_pipe = NULL;
418   memset (&priv->res, 0x00, sizeof (GstRTPSMediaWFDTypeFindResult));
419   priv->stream_bin = NULL;
420   priv->mux = NULL;
421   priv->mux_queue = NULL;
422   priv->pay = NULL;
423
424   g_mutex_init (&priv->lock);
425 }
426
427 static void
428 gst_rtsp_media_factory_wfd_finalize (GObject * obj)
429 {
430   GstRTSPMediaFactoryWFD *factory = GST_RTSP_MEDIA_FACTORY_WFD (obj);
431   GstRTSPMediaFactoryWFDPrivate *priv = factory->priv;
432
433   if (priv->permissions)
434     gst_rtsp_permissions_unref (priv->permissions);
435   g_free (priv->launch);
436   g_mutex_clear (&priv->lock);
437
438   g_mutex_clear (&priv->direct_lock);
439   g_cond_clear (&priv->direct_cond);
440
441   if (priv->audio_device)
442     g_free (priv->audio_device);
443   if (priv->audio_encoder_aac)
444     g_free (priv->audio_encoder_aac);
445   if (priv->audio_encoder_ac3)
446     g_free (priv->audio_encoder_ac3);
447
448   if (priv->video_encoder)
449     g_free (priv->video_encoder);
450
451   G_OBJECT_CLASS (gst_rtsp_media_factory_wfd_parent_class)->finalize (obj);
452 }
453
454 GstRTSPMediaFactoryWFD *
455 gst_rtsp_media_factory_wfd_new (void)
456 {
457   GstRTSPMediaFactoryWFD *result;
458
459   result = g_object_new (GST_TYPE_RTSP_MEDIA_FACTORY_WFD, NULL);
460
461   return result;
462 }
463
464 static void
465 gst_rtsp_media_factory_wfd_get_property (GObject * object,
466     guint propid, GValue * value, GParamSpec * pspec)
467 {
468   //GstRTSPMediaFactoryWFD *factory = GST_RTSP_MEDIA_FACTORY_WFD (object);
469
470   switch (propid) {
471     default:
472       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
473   }
474 }
475
476 static void
477 gst_rtsp_media_factory_wfd_set_property (GObject * object,
478     guint propid, const GValue * value, GParamSpec * pspec)
479 {
480   //GstRTSPMediaFactoryWFD *factory = GST_RTSP_MEDIA_FACTORY_WFD (object);
481
482   switch (propid) {
483     default:
484       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
485   }
486 }
487
488 static GstPadProbeReturn
489 rtsp_media_wfd_dump_data (GstPad * pad, GstPadProbeInfo * info, gpointer u_data)
490 {
491   guint8 *data;
492   gsize size;
493   FILE *f;
494   GstMapInfo mapinfo;
495
496   if (info->type == (GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_PUSH)) {
497     GstBuffer *buffer = gst_pad_probe_info_get_buffer (info);
498
499     gst_buffer_map (buffer, &mapinfo, GST_MAP_READ);
500     data = mapinfo.data;
501     size = gst_buffer_get_size (buffer);
502
503     f = fopen ("/root/probe.ts", "a");
504     if (f != NULL) {
505       fwrite (data, size, 1, f);
506       fclose (f);
507     }
508     gst_buffer_unmap (buffer, &mapinfo);
509   }
510
511   return GST_PAD_PROBE_OK;
512 }
513
514 static gboolean
515 _rtsp_media_factory_wfd_create_audio_capture_bin (GstRTSPMediaFactoryWFD *
516     factory, GstBin * srcbin)
517 {
518   GstElement *audiosrc = NULL;
519   GstElement *acaps = NULL;
520   GstElement *acaps2 = NULL;
521   GstElement *aenc = NULL;
522   GstElement *audio_convert = NULL;
523   GstElement *aqueue = NULL;
524   GstRTSPMediaFactoryWFDPrivate *priv = NULL;
525   GstStructure *audio_properties_name = NULL;
526
527   guint channels = 0;
528   gboolean is_enc_req = TRUE;
529   guint freq = 0;
530   gchar *acodec = NULL;
531
532   priv = factory->priv;
533
534   if (priv->audio_codec == GST_WFD_AUDIO_UNKNOWN) {
535     GST_INFO_OBJECT (factory, "Skip create audio source");
536     return TRUE;
537   }
538
539   priv->audio_srcbin = (GstBin *)gst_bin_new ("audio");
540   
541   /* create audio src element */
542   audiosrc = gst_element_factory_make ("pulsesrc", "audiosrc");
543   if (!audiosrc) {
544     GST_ERROR_OBJECT (factory, "failed to create audiosrc element");
545     goto create_error;
546   }
547
548   GST_INFO_OBJECT (factory, "audio device : %s", priv->audio_device);
549   GST_INFO_OBJECT (factory, "audio latency time  : %"G_GUINT64_FORMAT,
550       priv->audio_latency_time);
551   GST_INFO_OBJECT (factory, "audio_buffer_time  : %"G_GUINT64_FORMAT,
552       priv->audio_buffer_time);
553   GST_INFO_OBJECT (factory, "audio_do_timestamp  : %d",
554       priv->audio_do_timestamp);
555
556   audio_properties_name = gst_structure_new_from_string (priv->audio_device);
557
558   g_object_set (audiosrc, "stream-properties", audio_properties_name, NULL);
559   g_object_set (audiosrc, "buffer-time", (gint64) priv->audio_buffer_time,
560       NULL);
561   g_object_set (audiosrc, "latency-time", (gint64) priv->audio_latency_time,
562       NULL);
563   g_object_set (audiosrc, "do-timestamp", (gboolean) priv->audio_do_timestamp,
564       NULL);
565   g_object_set (audiosrc, "provide-clock", (gboolean) FALSE, NULL);
566   g_object_set (audiosrc, "is-live", (gboolean) TRUE, NULL);
567
568   if (priv->audio_codec == GST_WFD_AUDIO_LPCM) {
569     /* To meet miracast certification */
570     gint64 block_size = 1920;
571     g_object_set (audiosrc, "blocksize", (gint64) block_size, NULL);
572
573     audio_convert = gst_element_factory_make ("capssetter", "audio_convert");
574     if (NULL == audio_convert) {
575       GST_ERROR_OBJECT (factory, "failed to create audio convert element");
576       goto create_error;
577     }
578     g_object_set (audio_convert, "caps", gst_caps_new_simple ("audio/x-lpcm",
579             "width", G_TYPE_INT, 16,
580             "rate", G_TYPE_INT, 48000,
581             "channels", G_TYPE_INT, 2,
582             "dynamic_range", G_TYPE_INT, 0,
583             "emphasis", G_TYPE_BOOLEAN, FALSE,
584             "mute", G_TYPE_BOOLEAN, FALSE, NULL), NULL);
585     g_object_set (audio_convert, "join", (gboolean) FALSE, NULL);
586     g_object_set (audio_convert, "replace", (gboolean) TRUE, NULL);
587
588     acaps2 = gst_element_factory_make ("capsfilter", "audiocaps2");
589     if (NULL == acaps2) {
590       GST_ERROR_OBJECT (factory, "failed to create audio capsilfter element");
591       goto create_error;
592     }
593     /* In case of LPCM, uses big endian */
594     g_object_set (G_OBJECT (acaps2), "caps",
595         gst_caps_new_simple ("audio/x-raw", "format", G_TYPE_STRING, "S16BE",
596             /* In case of LPCM, uses big endian */
597             "rate", G_TYPE_INT, 48000,
598             "channels", G_TYPE_INT, 2, NULL), NULL);
599   }
600
601   /* create audio caps element */
602   acaps = gst_element_factory_make ("capsfilter", "audiocaps");
603   if (NULL == acaps) {
604     GST_ERROR_OBJECT (factory, "failed to create audio capsilfter element");
605     goto create_error;
606   }
607
608   if (priv->audio_channels == GST_WFD_CHANNEL_2)
609     channels = 2;
610   else if (priv->audio_channels == GST_WFD_CHANNEL_4)
611     channels = 4;
612   else if (priv->audio_channels == GST_WFD_CHANNEL_6)
613     channels = 6;
614   else if (priv->audio_channels == GST_WFD_CHANNEL_8)
615     channels = 8;
616   else
617     channels = 2;
618
619   if (priv->audio_freq == GST_WFD_FREQ_44100)
620     freq = 44100;
621   else if (priv->audio_freq == GST_WFD_FREQ_48000)
622     freq = 48000;
623   else
624     freq = 44100;
625
626   if (priv->audio_codec == GST_WFD_AUDIO_LPCM) {
627     g_object_set (G_OBJECT (acaps), "caps",
628         gst_caps_new_simple ("audio/x-lpcm", "width", G_TYPE_INT, 16,
629             "rate", G_TYPE_INT, 48000,
630             "channels", G_TYPE_INT, 2,
631             "dynamic_range", G_TYPE_INT, 0,
632             "emphasis", G_TYPE_BOOLEAN, FALSE,
633             "mute", G_TYPE_BOOLEAN, FALSE, NULL), NULL);
634   } else if ((priv->audio_codec == GST_WFD_AUDIO_AAC)
635       || (priv->audio_codec == GST_WFD_AUDIO_AC3)) {
636     g_object_set (G_OBJECT (acaps), "caps", gst_caps_new_simple ("audio/x-raw",
637             "endianness", G_TYPE_INT, 1234, "signed", G_TYPE_BOOLEAN, TRUE,
638             "depth", G_TYPE_INT, 16, "rate", G_TYPE_INT, freq, "channels",
639             G_TYPE_INT, channels, NULL), NULL);
640   }
641
642   if (priv->audio_codec == GST_WFD_AUDIO_AAC) {
643     acodec = g_strdup (priv->audio_encoder_aac);
644     is_enc_req = TRUE;
645   } else if (priv->audio_codec == GST_WFD_AUDIO_AC3) {
646     acodec = g_strdup (priv->audio_encoder_ac3);
647     is_enc_req = TRUE;
648   } else if (priv->audio_codec == GST_WFD_AUDIO_LPCM) {
649     GST_DEBUG_OBJECT (factory, "No codec required, raw data will be sent");
650     is_enc_req = FALSE;
651   } else {
652     GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
653     goto create_error;
654   }
655
656   if (is_enc_req) {
657     aenc = gst_element_factory_make (acodec, "audioenc");
658     if (NULL == aenc) {
659       GST_ERROR_OBJECT (factory, "failed to create audio encoder element");
660       goto create_error;
661     }
662
663     g_object_set (aenc, "compliance", -2, NULL);
664     g_object_set (aenc, "tolerance", 400000000, NULL);
665     g_object_set (aenc, "bitrate", (guint) 128000, NULL);
666     g_object_set (aenc, "rate-control", 2, NULL);
667
668     aqueue = gst_element_factory_make ("queue", "audio-queue");
669     if (!aqueue) {
670       GST_ERROR_OBJECT (factory, "failed to create audio queue element");
671       goto create_error;
672     }
673
674     gst_bin_add_many (priv->audio_srcbin, audiosrc, acaps, aenc, aqueue, NULL);
675     gst_bin_add (srcbin, GST_ELEMENT (priv->audio_srcbin));
676
677     if (!gst_element_link_many (audiosrc, acaps, aenc, aqueue, NULL)) {
678       GST_ERROR_OBJECT (factory, "Failed to link audio src elements...");
679       goto create_error;
680     }
681   } else {
682     aqueue = gst_element_factory_make ("queue", "audio-queue");
683     if (!aqueue) {
684       GST_ERROR_OBJECT (factory, "failed to create audio queue element");
685       goto create_error;
686     }
687
688     gst_bin_add_many (priv->audio_srcbin, audiosrc, acaps2, audio_convert, acaps, aqueue, NULL);
689     gst_bin_add (srcbin, GST_ELEMENT (priv->audio_srcbin));
690
691     if (!gst_element_link_many (audiosrc, acaps2, audio_convert, acaps, aqueue,
692             NULL)) {
693       GST_ERROR_OBJECT (factory, "Failed to link audio src elements...");
694       goto create_error;
695     }
696   }
697
698   priv->audio_queue = aqueue;
699   if (acodec)
700     g_free (acodec);
701   if (audio_properties_name)
702     gst_structure_free (audio_properties_name);
703   return TRUE;
704
705 create_error:
706   gst_object_unref (acaps);
707   gst_object_unref (aqueue);
708   if (acodec)
709     g_free (acodec);
710   if (audio_properties_name)
711     gst_structure_free (audio_properties_name);
712   return FALSE;
713 }
714
715 static gboolean
716 _rtsp_media_factory_wfd_create_videotest_bin (GstRTSPMediaFactoryWFD * factory,
717     GstBin * srcbin)
718 {
719   GstElement *videosrc = NULL;
720   GstElement *vcaps = NULL;
721   GstElement *videoconvert = NULL;
722   GstElement *venc_caps = NULL;
723   gchar *vcodec = NULL;
724   GstElement *venc = NULL;
725   GstElement *vparse = NULL;
726   GstElement *vqueue = NULL;
727   GstRTSPMediaFactoryWFDPrivate *priv = NULL;
728
729   priv = factory->priv;
730
731   GST_INFO_OBJECT (factory, "picked videotestsrc as video source");
732   priv->video_srcbin = (GstBin *)gst_bin_new ("video");
733
734   videosrc = gst_element_factory_make ("videotestsrc", "videosrc");
735   if (NULL == videosrc) {
736     GST_ERROR_OBJECT (factory, "failed to create ximagesrc element");
737     goto create_error;
738   }
739
740   /* create video caps element */
741   vcaps = gst_element_factory_make ("capsfilter", "videocaps");
742   if (NULL == vcaps) {
743     GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
744     goto create_error;
745   }
746
747   g_object_set (G_OBJECT (vcaps), "caps",
748       gst_caps_new_simple ("video/x-raw",
749           "format", G_TYPE_STRING, "I420",
750           "width", G_TYPE_INT, priv->video_width,
751           "height", G_TYPE_INT, priv->video_height,
752           "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
753       NULL);
754
755   /* create video convert element */
756   videoconvert = gst_element_factory_make ("videoconvert", "videoconvert");
757   if (NULL == videoconvert) {
758     GST_ERROR_OBJECT (factory, "failed to create video videoconvert element");
759     goto create_error;
760   }
761
762   venc_caps = gst_element_factory_make ("capsfilter", "venc_caps");
763   if (NULL == venc_caps) {
764     GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
765     goto create_error;
766   }
767
768   g_object_set (G_OBJECT (venc_caps), "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
796   vparse = gst_element_factory_make ("h264parse", "videoparse");
797   if (NULL == vparse) {
798     GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
799     goto create_error;
800   }
801   g_object_set (vparse, "config-interval", 1, NULL);
802
803   vqueue = gst_element_factory_make ("queue", "video-queue");
804   if (!vqueue) {
805     GST_ERROR_OBJECT (factory, "failed to create video queue element");
806     goto create_error;
807   }
808
809   gst_bin_add_many (priv->video_srcbin, videosrc, vcaps, videoconvert, venc_caps, venc, vparse, vqueue, NULL);
810   gst_bin_add (srcbin, GST_ELEMENT (priv->video_srcbin));
811   if (!gst_element_link_many (videosrc, vcaps, videoconvert, venc_caps, venc,
812           vparse, vqueue, NULL)) {
813     GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
814     goto create_error;
815   }
816
817   priv->video_queue = vqueue;
818   priv->venc = venc;
819
820   return TRUE;
821
822 create_error:
823   gst_object_unref(videosrc);
824   gst_object_unref(vcaps);
825   gst_object_unref(videoconvert);
826   gst_object_unref(venc_caps);
827   gst_object_unref(venc);
828   gst_object_unref(vparse);
829   gst_object_unref(vqueue);
830   return FALSE;
831 }
832
833 static gboolean
834 _rtsp_media_factory_wfd_create_waylandsrc_bin (GstRTSPMediaFactoryWFD * factory,
835     GstBin * srcbin)
836 {
837   GstElement *videosrc = NULL;
838   GstElement *vcaps = NULL;
839   gchar *vcodec = NULL;
840   GstElement *venc = NULL;
841   GstElement *vparse = NULL;
842   GstElement *vqueue = NULL;
843   GstRTSPMediaFactoryWFDPrivate *priv = NULL;
844
845   priv = factory->priv;
846
847   GST_INFO_OBJECT (factory, "picked waylandsrc as video source");
848
849   if (priv->video_codec == GST_WFD_VIDEO_UNKNOWN) {
850     GST_INFO_OBJECT (factory, "Skip create video source.");
851     return TRUE;
852   }
853
854   priv->video_srcbin = (GstBin *)gst_bin_new ("video");
855
856   videosrc = gst_element_factory_make ("waylandsrc", "videosrc");
857   if (NULL == videosrc) {
858     GST_ERROR_OBJECT (factory, "failed to create ximagesrc element");
859     goto create_error;
860   }
861
862   /* create video caps element */
863   vcaps = gst_element_factory_make ("capsfilter", "videocaps");
864   if (NULL == vcaps) {
865     GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
866     goto create_error;
867   }
868
869   g_object_set (G_OBJECT (vcaps), "caps",
870       gst_caps_new_simple ("video/x-raw",
871           "format", G_TYPE_STRING, "SN12",
872           "width", G_TYPE_INT, priv->video_width,
873           "height", G_TYPE_INT, priv->video_height,
874           "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
875       NULL);
876
877   if (priv->video_codec == GST_WFD_VIDEO_H264)
878     vcodec = g_strdup (priv->video_encoder);
879   else {
880     GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
881     goto create_error;
882   }
883
884   venc = gst_element_factory_make (vcodec, "videoenc");
885   if (vcodec)
886     g_free (vcodec);
887
888   if (!venc) {
889     GST_ERROR_OBJECT (factory, "failed to create video encoder element");
890     goto create_error;
891   }
892
893   g_object_set (venc, "aud", 0, NULL);
894   g_object_set (venc, "byte-stream", 1, NULL);
895   g_object_set (venc, "bitrate", 512, NULL);
896   g_object_set (venc, "target-bitrate", priv->video_bitrate, NULL);
897
898   vparse = gst_element_factory_make ("h264parse", "videoparse");
899   if (NULL == vparse) {
900     GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
901     goto create_error;
902   }
903   g_object_set (vparse, "config-interval", 1, NULL);
904
905   vqueue = gst_element_factory_make ("queue", "video-queue");
906   if (!vqueue) {
907     GST_ERROR_OBJECT (factory, "failed to create video queue element");
908     goto create_error;
909   }
910
911   gst_bin_add_many (priv->video_srcbin, videosrc, vcaps, venc, vparse, vqueue, NULL);
912   gst_bin_add (srcbin, GST_ELEMENT (priv->video_srcbin));
913   if (!gst_element_link_many (videosrc, vcaps, venc, vparse, vqueue, NULL)) {
914     GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
915     goto create_error;
916   }
917
918   priv->video_queue = vqueue;
919   priv->venc = venc;
920
921   return TRUE;
922
923 create_error:
924   gst_object_unref (videosrc);
925   gst_object_unref (vqueue);
926   return FALSE;
927 }
928
929 static gboolean
930 _rtsp_media_factory_wfd_create_camera_capture_bin (GstRTSPMediaFactoryWFD *
931     factory, GstBin * srcbin)
932 {
933   GstElement *videosrc = NULL;
934   GstElement *vcaps = NULL;
935   GstElement *venc = NULL;
936   GstElement *vparse = NULL;
937   GstElement *vqueue = NULL;
938   gchar *vcodec = NULL;
939   GstRTSPMediaFactoryWFDPrivate *priv = NULL;
940
941   priv = factory->priv;
942   priv->video_srcbin = (GstBin *)gst_bin_new ("video");
943
944   videosrc = gst_element_factory_make ("camerasrc", "videosrc");
945   if (NULL == videosrc) {
946     GST_ERROR_OBJECT (factory, "failed to create camerasrc element");
947     goto create_error;
948   }
949
950   /* create video caps element */
951   vcaps = gst_element_factory_make ("capsfilter", "videocaps");
952   if (NULL == vcaps) {
953     GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
954     goto create_error;
955   }
956
957   GST_INFO_OBJECT (factory, "picked camerasrc as video source");
958   g_object_set (G_OBJECT (vcaps), "caps",
959       gst_caps_new_simple ("video/x-raw",
960           "width", G_TYPE_INT, priv->video_width,
961           "height", G_TYPE_INT, priv->video_height,
962           "format", G_TYPE_STRING, "SN12",
963           "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
964       NULL);
965
966   if (priv->video_codec == GST_WFD_VIDEO_H264)
967     vcodec = g_strdup (priv->video_encoder);
968   else {
969     GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
970     goto create_error;
971   }
972
973   venc = gst_element_factory_make (vcodec, "videoenc");
974   if (vcodec)
975     g_free (vcodec);
976
977   if (!venc) {
978     GST_ERROR_OBJECT (factory, "failed to create video encoder element");
979     goto create_error;
980   }
981
982   g_object_set (venc, "bitrate", priv->video_bitrate, NULL);
983   g_object_set (venc, "byte-stream", 1, NULL);
984   g_object_set (venc, "append-dci", 1, NULL);
985
986   vparse = gst_element_factory_make ("h264parse", "videoparse");
987   if (NULL == vparse) {
988     GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
989     goto create_error;
990   }
991   g_object_set (vparse, "config-interval", 1, NULL);
992
993   vqueue = gst_element_factory_make ("queue", "video-queue");
994   if (!vqueue) {
995     GST_ERROR_OBJECT (factory, "failed to create video queue element");
996     goto create_error;
997   }
998
999   gst_bin_add_many (priv->video_srcbin, videosrc, vcaps, venc, vparse, vqueue, NULL);
1000   gst_bin_add (srcbin, GST_ELEMENT (priv->video_srcbin));
1001
1002   if (!gst_element_link_many (videosrc, vcaps, venc, vparse, vqueue, NULL)) {
1003     GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
1004     goto create_error;
1005   }
1006
1007   priv->video_queue = vqueue;
1008   priv->venc = venc;
1009
1010   return TRUE;
1011
1012 create_error:
1013   gst_object_unref (videosrc);
1014   gst_object_unref (vqueue);
1015   return FALSE;
1016 }
1017
1018 static gboolean
1019 _rtsp_media_factory_wfd_create_xcapture_bin (GstRTSPMediaFactoryWFD * factory,
1020     GstBin * srcbin)
1021 {
1022   GstElement *videosrc = NULL;
1023   GstElement *vcaps = NULL;
1024   GstElement *venc_caps = NULL;
1025   GstElement *videoconvert = NULL, *videoscale = 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 ximagesrc as video source");
1035   priv->video_srcbin = (GstBin *)gst_bin_new ("video");
1036
1037   videosrc = gst_element_factory_make ("ximagesrc", "videosrc");
1038   if (NULL == videosrc) {
1039     GST_ERROR_OBJECT (factory, "failed to create ximagesrc element");
1040     goto create_error;
1041   }
1042
1043   videoscale = gst_element_factory_make ("videoscale", "videoscale");
1044   if (NULL == videoscale) {
1045     GST_ERROR_OBJECT (factory, "failed to create videoscale element");
1046     goto create_error;
1047   }
1048
1049   videoconvert = gst_element_factory_make ("videoconvert", "videoconvert");
1050   if (NULL == videoconvert) {
1051     GST_ERROR_OBJECT (factory, "failed to create videoconvert element");
1052     goto create_error;
1053   }
1054
1055   /* create video caps element */
1056   vcaps = gst_element_factory_make ("capsfilter", "videocaps");
1057   if (NULL == vcaps) {
1058     GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
1059     goto create_error;
1060   }
1061
1062   g_object_set (G_OBJECT (vcaps), "caps",
1063       gst_caps_new_simple ("video/x-raw",
1064           "width", G_TYPE_INT, priv->video_width,
1065           "height", G_TYPE_INT, priv->video_height,
1066           "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
1067       NULL);
1068
1069   if (priv->video_codec == GST_WFD_VIDEO_H264)
1070     vcodec = g_strdup (priv->video_encoder);
1071   else {
1072     GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
1073     goto create_error;
1074   }
1075
1076   venc = gst_element_factory_make (vcodec, "videoenc");
1077   if (vcodec)
1078     g_free (vcodec);
1079
1080   if (!venc) {
1081     GST_ERROR_OBJECT (factory, "failed to create video encoder element");
1082     goto create_error;
1083   }
1084
1085   g_object_set (venc, "aud", 0, NULL);
1086   g_object_set (venc, "byte-stream", 1, NULL);
1087   g_object_set (venc, "bitrate", 512, NULL);
1088
1089   venc_caps = gst_element_factory_make ("capsfilter", "venc_caps");
1090   if (NULL == venc_caps) {
1091     GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
1092     goto create_error;
1093   }
1094
1095   g_object_set (G_OBJECT (venc_caps), "caps",
1096       gst_caps_new_simple ("video/x-h264",
1097           "profile", G_TYPE_STRING, "baseline", NULL), NULL);
1098
1099   vparse = gst_element_factory_make ("h264parse", "videoparse");
1100   if (NULL == vparse) {
1101     GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
1102     goto create_error;
1103   }
1104   g_object_set (vparse, "config-interval", 1, NULL);
1105
1106   vqueue = gst_element_factory_make ("queue", "video-queue");
1107   if (!vqueue) {
1108     GST_ERROR_OBJECT (factory, "failed to create video queue element");
1109     goto create_error;
1110   }
1111
1112   gst_bin_add_many (priv->video_srcbin, videosrc, videoscale, videoconvert, vcaps, venc,
1113       venc_caps, vparse, vqueue, NULL);
1114   gst_bin_add (srcbin, GST_ELEMENT (priv->video_srcbin));
1115   if (!gst_element_link_many (videosrc, videoscale, videoconvert, vcaps, venc,
1116           venc_caps, vparse, vqueue, NULL)) {
1117     GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
1118     goto create_error;
1119   }
1120
1121   priv->video_queue = vqueue;
1122   priv->venc = venc;
1123
1124   return TRUE;
1125
1126 create_error:
1127   gst_object_unref(videosrc);
1128   gst_object_unref(vcaps);
1129   gst_object_unref(venc_caps);
1130   gst_object_unref(videoconvert);
1131   gst_object_unref(videoscale);
1132   gst_object_unref(venc);
1133   gst_object_unref(vparse);
1134   gst_object_unref(vqueue);
1135   return FALSE;
1136 }
1137
1138 static gboolean
1139 _rtsp_media_factory_wfd_create_xvcapture_bin (GstRTSPMediaFactoryWFD * factory,
1140     GstBin * srcbin)
1141 {
1142   GstElement *videosrc = NULL;
1143   GstElement *vcaps = NULL;
1144   gchar *vcodec = NULL;
1145   GstElement *venc = NULL;
1146   GstElement *vparse = NULL;
1147   GstElement *vqueue = NULL;
1148   GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1149
1150   priv = factory->priv;
1151
1152   GST_INFO_OBJECT (factory, "picked xvimagesrc as video source");
1153   priv->video_srcbin = (GstBin *)gst_bin_new ("video");
1154
1155   videosrc = gst_element_factory_make ("xvimagesrc", "videosrc");
1156   if (NULL == videosrc) {
1157     GST_ERROR_OBJECT (factory, "failed to create xvimagesrc element");
1158     goto create_error;
1159   }
1160
1161   /* create video caps element */
1162   vcaps = gst_element_factory_make ("capsfilter", "videocaps");
1163   if (NULL == vcaps) {
1164     GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
1165     goto create_error;
1166   }
1167
1168   g_object_set (G_OBJECT (vcaps), "caps",
1169       gst_caps_new_simple ("video/x-raw",
1170           "width", G_TYPE_INT, priv->video_width,
1171           "height", G_TYPE_INT, priv->video_height,
1172           "format", G_TYPE_STRING, "SN12",
1173           "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
1174       NULL);
1175
1176   if (priv->video_codec == GST_WFD_VIDEO_H264) {
1177     vcodec = g_strdup (priv->video_encoder);
1178   } else {
1179     GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
1180     goto create_error;
1181   }
1182
1183   venc = gst_element_factory_make (vcodec, "videoenc");
1184   if (!venc) {
1185     GST_ERROR_OBJECT (factory, "failed to create video encoder element");
1186     goto create_error;
1187   }
1188   g_object_set (venc, "bitrate", priv->video_bitrate, NULL);
1189   g_object_set (venc, "byte-stream", 1, NULL);
1190   g_object_set (venc, "append-dci", 1, NULL);
1191   g_object_set (venc, "idr-period", 120, NULL);
1192   g_object_set (venc, "skip-inbuf", priv->video_enc_skip_inbuf_value, NULL);
1193
1194   vparse = gst_element_factory_make ("h264parse", "videoparse");
1195   if (NULL == vparse) {
1196     GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
1197     goto create_error;
1198   }
1199   g_object_set (vparse, "config-interval", 1, NULL);
1200
1201   vqueue = gst_element_factory_make ("queue", "video-queue");
1202   if (!vqueue) {
1203     GST_ERROR_OBJECT (factory, "failed to create video queue element");
1204     goto create_error;
1205   }
1206
1207   gst_bin_add_many (priv->video_srcbin, videosrc, vcaps, venc, vparse, vqueue, NULL);
1208   gst_bin_add (srcbin, GST_ELEMENT (priv->video_srcbin));
1209   if (!gst_element_link_many (videosrc, vcaps, venc, vparse, vqueue, NULL)) {
1210     GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
1211     goto create_error;
1212   }
1213
1214   priv->video_queue = vqueue;
1215   priv->venc = venc;
1216   if (vcodec)
1217     g_free (vcodec);
1218
1219   return TRUE;
1220
1221 create_error:
1222   gst_object_unref (videosrc);
1223   gst_object_unref (vqueue);
1224   if (vcodec)
1225     g_free (vcodec);
1226   return FALSE;
1227 }
1228
1229 static GstElement *
1230 _rtsp_media_factory_wfd_create_srcbin (GstRTSPMediaFactoryWFD * factory)
1231 {
1232   GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1233
1234   GstBin *srcbin = NULL;
1235   GstElement *mux = NULL;
1236   GstElement *mux_queue = NULL;
1237   GstElement *payload = NULL;
1238   GstPad *srcpad = NULL;
1239   GstPad *mux_vsinkpad = NULL;
1240   GstPad *mux_asinkpad = NULL;
1241   GstPad *ghost_pad = NULL;
1242
1243   priv = factory->priv;
1244
1245   /* create source bin */
1246   srcbin = GST_BIN (gst_bin_new ("srcbin"));
1247   if (!srcbin) {
1248     GST_ERROR_OBJECT (factory, "failed to create source bin...");
1249     goto create_error;
1250   }
1251
1252   GST_INFO_OBJECT (factory, "Check video codec... %d", priv->video_codec);
1253   /* create video src element */
1254   switch (priv->videosrc_type) {
1255     case GST_WFD_VSRC_XIMAGESRC:
1256       if (!_rtsp_media_factory_wfd_create_xcapture_bin (factory, srcbin)) {
1257         GST_ERROR_OBJECT (factory, "failed to create xcapture bin...");
1258         goto create_error;
1259       }
1260       break;
1261     case GST_WFD_VSRC_XVIMAGESRC:
1262       if (!_rtsp_media_factory_wfd_create_xvcapture_bin (factory, srcbin)) {
1263         GST_ERROR_OBJECT (factory, "failed to create xvcapture bin...");
1264         goto create_error;
1265       }
1266       break;
1267     case GST_WFD_VSRC_CAMERASRC:
1268       if (!_rtsp_media_factory_wfd_create_camera_capture_bin (factory, srcbin)) {
1269         GST_ERROR_OBJECT (factory, "failed to create camera capture bin...");
1270         goto create_error;
1271       }
1272       break;
1273     case GST_WFD_VSRC_VIDEOTESTSRC:
1274       if (!_rtsp_media_factory_wfd_create_videotest_bin (factory, srcbin)) {
1275         GST_ERROR_OBJECT (factory, "failed to create videotestsrc bin...");
1276         goto create_error;
1277       }
1278       break;
1279     case GST_WFD_VSRC_WAYLANDSRC:
1280       if (!_rtsp_media_factory_wfd_create_waylandsrc_bin (factory, srcbin)) {
1281         GST_ERROR_OBJECT (factory, "failed to create videotestsrc bin...");
1282         goto create_error;
1283       }
1284       break;
1285     default:
1286       GST_ERROR_OBJECT (factory, "unknow mode selected...");
1287       goto create_error;
1288   }
1289
1290   mux = gst_element_factory_make ("mpegtsmux", "tsmux");
1291   if (!mux) {
1292     GST_ERROR_OBJECT (factory, "failed to create muxer element");
1293     goto create_error;
1294   }
1295
1296   g_object_set (mux, "wfd-mode", TRUE, NULL);
1297
1298   mux_queue = gst_element_factory_make ("queue", "muxer-queue");
1299   if (!mux_queue) {
1300     GST_ERROR_OBJECT (factory, "failed to create muxer-queue element");
1301     goto create_error;
1302   }
1303
1304   g_object_set (mux_queue, "max-size-buffers", 20000, NULL);
1305
1306   payload = gst_element_factory_make ("rtpmp2tpay", "pay0");
1307   if (!payload) {
1308     GST_ERROR_OBJECT (factory, "failed to create payload element");
1309     goto create_error;
1310   }
1311
1312   g_object_set (payload, "pt", 33, NULL);
1313   g_object_set (payload, "mtu", priv->mtu_size, NULL);
1314   g_object_set (payload, "rtp-flush", (gboolean) TRUE, NULL);
1315
1316   gst_bin_add_many (srcbin, mux, mux_queue, payload, NULL);
1317
1318   if (!gst_element_link_many (mux, mux_queue, payload, NULL)) {
1319     GST_ERROR_OBJECT (factory, "Failed to link muxer & payload...");
1320     goto create_error;
1321   }
1322
1323   if (priv->video_codec > GST_WFD_VIDEO_UNKNOWN) {
1324     /* request video sink pad from muxer, which has elementary pid 0x1011 */
1325     mux_vsinkpad = gst_element_get_request_pad (mux, "sink_4113");
1326     if (!mux_vsinkpad) {
1327       GST_ERROR_OBJECT (factory, "Failed to get sink pad from muxer...");
1328       goto create_error;
1329     }
1330
1331     /* request srcpad from video queue */
1332     srcpad = gst_element_get_static_pad (priv->video_queue, "src");
1333     if (!srcpad) {
1334       GST_ERROR_OBJECT (factory, "Failed to get srcpad from video queue...");
1335       goto create_error;
1336     }
1337   ghost_pad = gst_ghost_pad_new ("video_src", srcpad);
1338   gst_element_add_pad (GST_ELEMENT (priv->video_srcbin), ghost_pad);
1339
1340   if (gst_pad_link (ghost_pad, mux_vsinkpad) != GST_PAD_LINK_OK) {
1341       GST_ERROR_OBJECT (factory,
1342           "Failed to link video queue src pad & muxer video sink pad...");
1343       goto create_error;
1344     }
1345
1346     gst_object_unref (mux_vsinkpad);
1347     gst_object_unref (srcpad);
1348     srcpad = NULL;
1349   ghost_pad = NULL;
1350   }
1351
1352   GST_INFO_OBJECT (factory, "Check audio codec... %d", priv->audio_codec);
1353
1354   /* create audio source elements & add to pipeline */
1355   if (!_rtsp_media_factory_wfd_create_audio_capture_bin (factory, srcbin))
1356     goto create_error;
1357
1358   if (priv->audio_codec > GST_WFD_AUDIO_UNKNOWN) {
1359     /* request audio sink pad from muxer, which has elementary pid 0x1100 */
1360     mux_asinkpad = gst_element_get_request_pad (mux, "sink_4352");
1361     if (!mux_asinkpad) {
1362       GST_ERROR_OBJECT (factory, "Failed to get sinkpad from muxer...");
1363       goto create_error;
1364     }
1365
1366     /* request srcpad from audio queue */
1367     srcpad = gst_element_get_static_pad (priv->audio_queue, "src");
1368     if (!srcpad) {
1369       GST_ERROR_OBJECT (factory, "Failed to get srcpad from audio queue...");
1370       goto create_error;
1371     }
1372   ghost_pad = gst_ghost_pad_new ("audio_src", srcpad);
1373   gst_element_add_pad (GST_ELEMENT (priv->audio_srcbin), ghost_pad);
1374
1375     /* link audio queue's srcpad & muxer sink pad */
1376   if (gst_pad_link (ghost_pad, mux_asinkpad) != GST_PAD_LINK_OK) {
1377       GST_ERROR_OBJECT (factory,
1378           "Failed to link audio queue src pad & muxer audio sink pad...");
1379       goto create_error;
1380     }
1381     gst_object_unref (mux_asinkpad);
1382     gst_object_unref (srcpad);
1383   }
1384
1385   if (priv->dump_ts)
1386   {
1387     GstPad *pad_probe = NULL;
1388     pad_probe = gst_element_get_static_pad (mux, "src");
1389
1390     if (NULL == pad_probe) {
1391       GST_INFO_OBJECT (factory, "pad for probe not created");
1392     } else {
1393       GST_INFO_OBJECT (factory, "pad for probe SUCCESSFUL");
1394     }
1395     gst_pad_add_probe (pad_probe, GST_PAD_PROBE_TYPE_BUFFER,
1396         rtsp_media_wfd_dump_data, factory, NULL);
1397     if (pad_probe)
1398       gst_object_unref (pad_probe);
1399   }
1400
1401   GST_DEBUG_OBJECT (factory, "successfully created source bin...");
1402
1403   priv->stream_bin = srcbin;
1404   priv->mux = gst_object_ref (mux);
1405   priv->mux_queue = gst_object_ref (mux_queue);
1406   priv->pay = gst_object_ref (payload);
1407
1408   return GST_ELEMENT_CAST (srcbin);
1409
1410 create_error:
1411   GST_ERROR_OBJECT (factory, "Failed to create pipeline");
1412   if (mux_vsinkpad)
1413     gst_object_unref (mux_vsinkpad);
1414   if (mux_asinkpad)
1415     gst_object_unref (mux_asinkpad);
1416   if (srcpad)
1417     gst_object_unref (srcpad);
1418   if (srcbin)
1419     gst_object_unref (srcbin);
1420   return NULL;
1421 }
1422
1423 static GstElement *
1424 rtsp_media_factory_wfd_create_element (GstRTSPMediaFactory * factory,
1425     const GstRTSPUrl * url)
1426 {
1427   GstRTSPMediaFactoryWFD *_factory = GST_RTSP_MEDIA_FACTORY_WFD_CAST (factory);
1428   GstElement *element = NULL;
1429
1430   GST_RTSP_MEDIA_FACTORY_WFD_LOCK (factory);
1431
1432   element = _rtsp_media_factory_wfd_create_srcbin (_factory);
1433
1434   GST_RTSP_MEDIA_FACTORY_WFD_UNLOCK (factory);
1435
1436   return element;
1437 }
1438
1439 static GstRTSPMedia *
1440 rtsp_media_factory_wfd_construct (GstRTSPMediaFactory * factory,
1441     const GstRTSPUrl * url)
1442 {
1443   GstRTSPMedia *media;
1444   GstElement *element, *pipeline;
1445   GstRTSPMediaFactoryClass *klass;
1446
1447   klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
1448
1449   if (!klass->create_pipeline)
1450     goto no_create;
1451
1452   element = gst_rtsp_media_factory_create_element (factory, url);
1453   if (element == NULL)
1454     goto no_element;
1455
1456   /* create a new empty media */
1457   media = gst_rtsp_media_new (element);
1458   //media = g_object_new (GST_TYPE_RTSP_MEDIA_EXT, "element", element, NULL);
1459
1460   gst_rtsp_media_collect_streams (media);
1461
1462   pipeline = klass->create_pipeline (factory, media);
1463   if (pipeline == NULL)
1464     goto no_pipeline;
1465
1466   return media;
1467
1468   /* ERRORS */
1469 no_create:
1470   {
1471     g_critical ("no create_pipeline function");
1472     return NULL;
1473   }
1474 no_element:
1475   {
1476     g_critical ("could not create element");
1477     return NULL;
1478   }
1479 no_pipeline:
1480   {
1481     g_critical ("can't create pipeline");
1482     g_object_unref (media);
1483     return NULL;
1484   }
1485 }
1486
1487 gint type_detected = FALSE;
1488 gint linked = FALSE;
1489 static gint in_pad_probe;
1490
1491 static GstPadProbeReturn
1492 _rtsp_media_factory_wfd_restore_pipe_probe_cb (GstPad *pad, GstPadProbeInfo *info, gpointer user_data)
1493 {
1494   GstPad *old_src = NULL;
1495   GstPad *sink = NULL;
1496   GstPad *old_sink = NULL;
1497   GstPad *new_src = NULL;
1498   GstRTSPMediaFactoryWFD *factory = NULL;
1499   GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1500   GstRTSPMediaWFDDirectPipelineData *pipe_data = NULL;
1501
1502   if (!g_atomic_int_compare_and_exchange (&in_pad_probe, FALSE, TRUE))
1503     return GST_PAD_PROBE_OK;
1504
1505   factory = (GstRTSPMediaFactoryWFD *) user_data;
1506   priv = factory->priv;
1507   pipe_data = priv->direct_pipe;
1508
1509   gst_element_sync_state_with_parent (GST_ELEMENT(priv->audio_srcbin));
1510   gst_element_sync_state_with_parent (GST_ELEMENT(priv->video_srcbin));
1511   gst_element_sync_state_with_parent (GST_ELEMENT(priv->mux));
1512   gst_element_sync_state_with_parent (GST_ELEMENT(priv->mux_queue));
1513
1514   sink = gst_element_get_static_pad (priv->pay, "sink");
1515   old_src = gst_pad_get_peer (sink);
1516   gst_pad_unlink (old_src, sink);
1517
1518   new_src = gst_element_get_static_pad (priv->mux_queue, "src");
1519   old_sink = gst_pad_get_peer (new_src);
1520   gst_pad_unlink (new_src, old_sink);
1521   gst_element_set_state (priv->stub_fs, GST_STATE_NULL);
1522   gst_bin_remove ((GstBin *)priv->stream_bin, priv->stub_fs);
1523
1524   gst_pad_link (new_src, sink);
1525   gst_object_unref (new_src);
1526   gst_object_unref (old_sink);
1527
1528   gst_element_set_state (GST_ELEMENT(pipe_data->pipeline), GST_STATE_PAUSED);
1529
1530   /* signal that new pipeline linked */
1531   g_mutex_lock (&priv->direct_lock);
1532   g_cond_signal (&priv->direct_cond);
1533   linked = TRUE;
1534   g_mutex_unlock (&priv->direct_lock);
1535
1536   return GST_PAD_PROBE_REMOVE;
1537 }
1538
1539 static gboolean
1540 _rtsp_media_factory_wfd_destroy_direct_pipe(void *user_data)
1541 {
1542   GstRTSPMediaFactoryWFD *factory = NULL;
1543   GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1544   GstRTSPMediaWFDDirectPipelineData *pipe_data = NULL;
1545
1546   factory = (GstRTSPMediaFactoryWFD *) user_data;
1547   priv = factory->priv;
1548   pipe_data = priv->direct_pipe;
1549
1550   GST_DEBUG_OBJECT (factory, "Deleting pipeline");
1551   gst_element_set_state (GST_ELEMENT(pipe_data->pipeline), GST_STATE_NULL);
1552   gst_bin_remove ((GstBin *)priv->stream_bin, GST_ELEMENT(pipe_data->pipeline));
1553   g_free (pipe_data);
1554   g_signal_emit (factory,
1555       gst_rtsp_media_factory_wfd_signals[SIGNAL_DIRECT_STREAMING_END], 0, NULL);
1556   return FALSE;
1557 }
1558
1559 static void
1560 _rtsp_media_factory_wfd_demux_pad_added_cb (GstElement *element,
1561               GstPad     *pad,
1562               gpointer    data)
1563 {
1564   GstPad *sinkpad = NULL;
1565   GstRTSPMediaFactoryWFD *factory = NULL;
1566   GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1567   GstRTSPMediaWFDDirectPipelineData *pipe_data = NULL;
1568
1569   GstCaps *caps = gst_pad_get_current_caps (pad);
1570   gchar *pad_name = gst_pad_get_name (pad);
1571   gchar *pad_caps = gst_caps_to_string (caps);
1572   gst_caps_unref (caps);
1573
1574   factory = (GstRTSPMediaFactoryWFD *) data;
1575   priv = factory->priv;
1576   pipe_data = priv->direct_pipe;
1577
1578   if (g_strrstr (g_ascii_strdown(pad_caps, -1), "audio")) {
1579     sinkpad = gst_element_get_static_pad (pipe_data->ap, "sink");
1580     if (gst_pad_is_linked (sinkpad)) {
1581       gst_object_unref (sinkpad);
1582       g_free (pad_caps);
1583       g_free (pad_name);
1584       GST_DEBUG_OBJECT (factory, "pad linked");
1585       return;
1586     }
1587     if (gst_pad_link (pad, sinkpad) != GST_PAD_LINK_OK)
1588       GST_DEBUG_OBJECT (factory, "can't link demux %s pad", pad_name);
1589
1590     gst_object_unref (sinkpad);
1591     sinkpad = NULL;
1592   }
1593   if (g_strrstr (g_ascii_strdown(pad_caps, -1), "video")) {
1594     if (g_strrstr (g_ascii_strdown(pad_caps, -1), "h264")) {
1595       sinkpad = gst_element_get_static_pad (pipe_data->vp, "sink");
1596       if (gst_pad_link (pad, sinkpad) != GST_PAD_LINK_OK)
1597         GST_DEBUG_OBJECT (factory, "can't link demux %s pad", pad_name);
1598
1599       gst_object_unref (sinkpad);
1600       sinkpad = NULL;
1601     }
1602   }
1603
1604   g_free (pad_caps);
1605   g_free (pad_name);
1606 }
1607
1608 static GstPadProbeReturn
1609 _rtsp_media_factory_wfd_pay_pad_probe_cb (GstPad *pad, GstPadProbeInfo *info, gpointer user_data)
1610 {
1611   GstPad *old_src = NULL;
1612   GstPad *sink = NULL;
1613   GstPad *old_sink = NULL;
1614   GstPad *new_src = NULL;
1615   GstPad *fas_sink = NULL;
1616   GstPad *gp = NULL;
1617   GstRTSPMediaFactoryWFD *factory = NULL;
1618   GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1619   GstRTSPMediaWFDDirectPipelineData *pipe_data = NULL;
1620
1621   if (!g_atomic_int_compare_and_exchange (&in_pad_probe, FALSE, TRUE))
1622     return GST_PAD_PROBE_OK;
1623
1624   factory = (GstRTSPMediaFactoryWFD *) user_data;
1625   priv = factory->priv;
1626   pipe_data = priv->direct_pipe;
1627
1628   sink = gst_element_get_static_pad (priv->pay, "sink");
1629   old_src = gst_pad_get_peer (sink);
1630   gst_pad_unlink (old_src, sink);
1631
1632   new_src = gst_element_get_static_pad (pipe_data->tsmux, "src");
1633   old_sink = gst_pad_get_peer (new_src);
1634   gst_pad_unlink (new_src, old_sink);
1635   gst_element_set_state (pipe_data->mux_fs, GST_STATE_NULL);
1636   gst_bin_remove ((GstBin *)pipe_data->pipeline, pipe_data->mux_fs);
1637
1638   gp = gst_ghost_pad_new ("audio_file", new_src);
1639   gst_pad_set_active(gp,TRUE);
1640   gst_element_add_pad (GST_ELEMENT (pipe_data->pipeline), gp);
1641   gst_pad_link (gp, sink);
1642   gst_object_unref (new_src);
1643   gst_object_unref (old_sink);
1644
1645   priv->stub_fs = gst_element_factory_make ("fakesink", NULL);
1646   gst_bin_add (priv->stream_bin, priv->stub_fs);
1647   gst_element_sync_state_with_parent (priv->stub_fs);
1648   fas_sink = gst_element_get_static_pad (priv->stub_fs, "sink");
1649   gst_pad_link (old_src, fas_sink);
1650   gst_object_unref (old_src);
1651   gst_object_unref (fas_sink);
1652   gst_element_set_state (GST_ELEMENT(priv->audio_srcbin), GST_STATE_PAUSED);
1653   gst_element_set_state (GST_ELEMENT(priv->video_srcbin), GST_STATE_PAUSED);
1654   gst_element_set_state (GST_ELEMENT(priv->mux), GST_STATE_PAUSED);
1655   gst_element_set_state (GST_ELEMENT(priv->mux_queue), GST_STATE_PAUSED);
1656
1657   /* signal that new pipeline linked */
1658   g_mutex_lock (&priv->direct_lock);
1659   linked = TRUE;
1660   g_cond_signal (&priv->direct_cond);
1661   g_mutex_unlock (&priv->direct_lock);
1662
1663   return GST_PAD_PROBE_REMOVE;
1664 }
1665
1666 static gboolean
1667 _rtsp_media_factory_wfd_relink_pipeline(GstRTSPMediaFactoryWFD * factory)
1668 {
1669   GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1670   GstPad *probe_pad = NULL;
1671   gint64 end_time = 0;
1672
1673   priv = factory->priv;
1674
1675   probe_pad = gst_element_get_static_pad (priv->pay, "sink");
1676   if (probe_pad == NULL)
1677     return FALSE;
1678
1679   in_pad_probe = FALSE;
1680   linked = FALSE;
1681   gst_pad_add_probe (probe_pad, GST_PAD_PROBE_TYPE_IDLE, _rtsp_media_factory_wfd_restore_pipe_probe_cb, factory, NULL);
1682
1683   g_mutex_lock (&factory->priv->direct_lock);
1684   end_time = g_get_monotonic_time () + 5 * G_TIME_SPAN_SECOND;
1685   if (!g_cond_wait_until (&factory->priv->direct_cond, &factory->priv->direct_lock, end_time)) {
1686     g_mutex_unlock (&factory->priv->direct_lock);
1687     GST_ERROR_OBJECT (factory, "Failed to relink pipeline");
1688     return linked;
1689   }
1690   g_mutex_unlock (&factory->priv->direct_lock);
1691   return linked;
1692 }
1693
1694
1695 static GstPadProbeReturn
1696 _rtsp_media_factory_wfd_src_pad_probe_cb(GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1697 {
1698   GstRTSPMediaFactoryWFD *factory = NULL;
1699   GstEvent *event = GST_PAD_PROBE_INFO_EVENT(info);
1700
1701   factory = (GstRTSPMediaFactoryWFD *) user_data;
1702
1703   if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
1704     GST_INFO_OBJECT (factory, "Got event: %s in direct streaming", GST_EVENT_TYPE_NAME (event));
1705     info->data = NULL;
1706     info->data = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, gst_structure_new_empty ("fillEOS"));
1707
1708     if (!_rtsp_media_factory_wfd_relink_pipeline(factory)) {
1709       GST_ERROR_OBJECT (factory, "Failed to relink pipeline");
1710       return GST_PAD_PROBE_REMOVE;
1711     }
1712
1713     g_idle_add((GSourceFunc)_rtsp_media_factory_wfd_destroy_direct_pipe, factory);
1714     return GST_PAD_PROBE_REMOVE;
1715   }
1716
1717   return GST_PAD_PROBE_OK;
1718 }
1719
1720 static gboolean
1721 _rtsp_media_factory_wfd_create_direct_pipeline(GstRTSPMediaFactoryWFD * factory)
1722 {
1723   GstElement *src = NULL;
1724   GstElement *demux = NULL;
1725   gchar *path = NULL;
1726   GstPad *srcpad = NULL;
1727   GstPad *mux_vsinkpad = NULL;
1728   GstPad *mux_asinkpad = NULL;
1729   GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1730   GstRTSPMediaWFDDirectPipelineData *pipe_data = NULL;
1731
1732   priv = factory->priv;
1733   pipe_data = priv->direct_pipe;
1734
1735   pipe_data->pipeline = (GstBin *) gst_bin_new ("direct");
1736
1737   src = gst_element_factory_create(priv->res.src_fact, NULL);
1738   demux = gst_element_factory_create(priv->res.demux_fact, NULL);
1739   pipe_data->ap = gst_element_factory_make ("aacparse", NULL);
1740   pipe_data->vp = gst_element_factory_make ("h264parse", NULL);
1741   pipe_data->aq = gst_element_factory_make ("queue", NULL);
1742   pipe_data->vq = gst_element_factory_make ("queue", NULL);
1743   pipe_data->tsmux = gst_element_factory_make ("mpegtsmux", NULL);
1744   pipe_data->mux_fs = gst_element_factory_make ("fakesink", NULL);
1745
1746   if (src == NULL || demux == NULL || pipe_data->tsmux == NULL ||
1747       pipe_data->ap == NULL || pipe_data->vp == NULL ||
1748       pipe_data->aq == NULL || pipe_data->vq == NULL ||
1749       pipe_data->mux_fs == NULL) {
1750     GST_ERROR_OBJECT (factory, "Not all element created");
1751     return FALSE;
1752   }
1753
1754   if (g_strrstr (g_ascii_strdown(g_type_name(G_OBJECT_TYPE(src)), -1), "file")) {
1755     path = g_filename_from_uri (pipe_data->uri, NULL, NULL);
1756     if (path == NULL) {
1757       GST_ERROR_OBJECT(factory, "No file path");
1758       return FALSE;
1759     }
1760     g_object_set (src, "location", path, NULL);
1761     g_free (path);
1762   } else
1763     g_object_set (src, "uri", pipe_data->uri, NULL);
1764
1765   gst_bin_add_many (pipe_data->pipeline, src, demux, pipe_data->ap,
1766       pipe_data->vp, pipe_data->aq, pipe_data->vq,
1767       pipe_data->tsmux, pipe_data->mux_fs, NULL);
1768
1769   if (!gst_element_link (src, demux)) {
1770     GST_ERROR_OBJECT (factory, "Can't link src with demux");
1771     return FALSE;
1772   }
1773
1774   if (!gst_element_link (pipe_data->ap, pipe_data->aq)) {
1775     GST_ERROR_OBJECT (factory, "Can't link audio parse and queue");
1776     return FALSE;
1777   }
1778
1779   if (!gst_element_link (pipe_data->vp, pipe_data->vq)) {
1780     GST_ERROR_OBJECT (factory, "Can't link video parse and queue");
1781     return FALSE;
1782   }
1783
1784   if (!gst_element_link (pipe_data->tsmux, pipe_data->mux_fs)) {
1785     GST_DEBUG_OBJECT (factory, "Can't link muxer and fakesink");
1786     return FALSE;
1787   }
1788
1789   g_signal_connect_object (demux, "pad-added", G_CALLBACK (_rtsp_media_factory_wfd_demux_pad_added_cb), factory, 0);
1790
1791   gst_bin_add (priv->stream_bin, GST_ELEMENT (pipe_data->pipeline));
1792
1793
1794   /* request video sink pad from muxer, which has elementary pid 0x1011 */
1795   mux_vsinkpad = gst_element_get_request_pad (pipe_data->tsmux, "sink_4113");
1796   if (!mux_vsinkpad) {
1797     GST_ERROR_OBJECT (factory, "Failed to get sink pad from muxer...");
1798     return FALSE;
1799   }
1800
1801   /* request srcpad from video queue */
1802   srcpad = gst_element_get_static_pad (pipe_data->vq, "src");
1803   if (!srcpad) {
1804     GST_ERROR_OBJECT (factory, "Failed to get srcpad from video queue...");
1805   }
1806
1807   if (gst_pad_link (srcpad, mux_vsinkpad) != GST_PAD_LINK_OK) {
1808     GST_ERROR_OBJECT (factory, "Failed to link video queue src pad & muxer video sink pad...");
1809     return FALSE;
1810   }
1811
1812   gst_object_unref (mux_vsinkpad);
1813   gst_object_unref (srcpad);
1814   srcpad = NULL;
1815
1816   /* request audio sink pad from muxer, which has elementary pid 0x1100 */
1817   mux_asinkpad = gst_element_get_request_pad (pipe_data->tsmux, "sink_4352");
1818   if (!mux_asinkpad) {
1819     GST_ERROR_OBJECT (factory, "Failed to get sinkpad from muxer...");
1820     return FALSE;
1821   }
1822
1823   /* request srcpad from audio queue */
1824   srcpad = gst_element_get_static_pad (pipe_data->aq, "src");
1825   if (!srcpad) {
1826     GST_ERROR_OBJECT (factory, "Failed to get srcpad from audio queue...");
1827     return FALSE;
1828   }
1829
1830   /* link audio queue's srcpad & muxer sink pad */
1831   if (gst_pad_link (srcpad, mux_asinkpad) != GST_PAD_LINK_OK) {
1832     GST_ERROR_OBJECT (factory, "Failed to link audio queue src pad & muxer audio sink pad...");
1833     return FALSE;
1834   }
1835   gst_object_unref (mux_asinkpad);
1836   gst_object_unref (srcpad);
1837   srcpad = NULL;
1838
1839   gst_element_sync_state_with_parent (GST_ELEMENT (pipe_data->pipeline));
1840
1841   srcpad = gst_element_get_static_pad (priv->pay, "sink");
1842
1843   in_pad_probe = FALSE;
1844   gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_IDLE, _rtsp_media_factory_wfd_pay_pad_probe_cb, factory, NULL);
1845   gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, _rtsp_media_factory_wfd_src_pad_probe_cb, factory, NULL);
1846
1847   return TRUE;
1848 }
1849
1850 static void
1851 _rtsp_media_factory_wfd_decodebin_element_added_cb (GstElement *decodebin,
1852         GstElement *child, void *user_data)
1853 {
1854   gchar *elem_name = g_ascii_strdown(g_type_name(G_OBJECT_TYPE(child)), -1);
1855   GstRTSPMediaFactoryWFD *factory = NULL;
1856   GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1857
1858   factory = (GstRTSPMediaFactoryWFD *) user_data;
1859   priv = factory->priv;
1860
1861   if (g_strrstr (elem_name, "h264"))
1862     priv->res.h264_found++;
1863   if (g_strrstr (elem_name, "aac"))
1864     priv->res.aac_found++;
1865   if (g_strrstr (elem_name, "ac3"))
1866     priv->res.ac3_found++;
1867   if (g_strrstr (elem_name, "demux"))
1868     priv->res.demux_fact = gst_element_get_factory(child);
1869 }
1870
1871 static void
1872 _rtsp_media_factory_wfd_uridecodebin_element_added_cb (GstElement *uridecodebin,
1873         GstElement *child, void *user_data)
1874 {
1875   GstRTSPMediaFactoryWFD *factory = NULL;
1876   GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1877
1878   factory = (GstRTSPMediaFactoryWFD *) user_data;
1879   priv = factory->priv;
1880
1881   if (g_strrstr (g_ascii_strdown(g_type_name(G_OBJECT_TYPE(child)), -1), "src"))
1882     priv->res.src_fact = gst_element_get_factory(child);
1883
1884   if (G_OBJECT_TYPE(child) == priv->decodebin_type)
1885     g_signal_connect_object (child, "element-added",
1886         G_CALLBACK (_rtsp_media_factory_wfd_decodebin_element_added_cb), factory, 0);
1887 }
1888
1889 static void
1890 _rtsp_media_factory_wfd_discover_pad_added_cb (GstElement *uridecodebin, GstPad *pad,
1891     GstBin *pipeline)
1892 {
1893   GstPad *sinkpad = NULL;
1894   GstCaps *caps;
1895
1896   GstElement *queue = gst_element_factory_make ("queue", NULL);
1897   GstElement *sink = gst_element_factory_make ("fakesink", NULL);
1898
1899   if (G_UNLIKELY (queue == NULL || sink == NULL))
1900     goto error;
1901
1902   g_object_set (sink, "silent", TRUE, NULL);
1903   g_object_set (queue, "max-size-buffers", 1, "silent", TRUE, NULL);
1904
1905   caps = gst_pad_query_caps (pad, NULL);
1906
1907   sinkpad = gst_element_get_static_pad (queue, "sink");
1908   if (sinkpad == NULL)
1909     goto error;
1910
1911   gst_caps_unref (caps);
1912
1913   gst_bin_add_many (pipeline, queue, sink, NULL);
1914
1915   if (!gst_element_link_pads_full (queue, "src", sink, "sink",
1916           GST_PAD_LINK_CHECK_NOTHING))
1917     goto error;
1918   if (!gst_element_sync_state_with_parent (sink))
1919     goto error;
1920   if (!gst_element_sync_state_with_parent (queue))
1921     goto error;
1922
1923   if (gst_pad_link_full (pad, sinkpad,
1924           GST_PAD_LINK_CHECK_NOTHING) != GST_PAD_LINK_OK)
1925     goto error;
1926   gst_object_unref (sinkpad);
1927
1928   return;
1929
1930 error:
1931   if (sinkpad)
1932     gst_object_unref (sinkpad);
1933   if (queue)
1934     gst_object_unref (queue);
1935   if (sink)
1936     gst_object_unref (sink);
1937   return;
1938 }
1939
1940 static void
1941 _rtsp_media_factory_wfd_uridecode_no_pad_cb (GstElement * uridecodebin, void * user_data)
1942 {
1943   GstRTSPMediaFactoryWFD *factory = NULL;
1944   GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1945
1946   factory = (GstRTSPMediaFactoryWFD *) user_data;
1947   priv = factory->priv;
1948   type_detected = TRUE;
1949   g_main_loop_quit (priv->discover_loop);
1950 }
1951
1952 static void
1953 _rtsp_media_factory_wfd_discover_pipe_bus_call (GstBus *bus,
1954           GstMessage *msg,
1955           gpointer data)
1956 {
1957   GstRTSPMediaFactoryWFD *factory = NULL;
1958   GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1959
1960   factory = (GstRTSPMediaFactoryWFD *) data;
1961   priv = factory->priv;
1962
1963   switch (GST_MESSAGE_TYPE (msg)) {
1964     case GST_MESSAGE_ERROR: {
1965       gchar  *debug;
1966       GError *error;
1967
1968       gst_message_parse_error (msg, &error, &debug);
1969       g_free (debug);
1970
1971       GST_ERROR_OBJECT (factory, "Error: %s", error->message);
1972       g_error_free (error);
1973
1974       type_detected = FALSE;
1975       g_main_loop_quit (priv->discover_loop);
1976       break;
1977     }
1978     default:
1979       break;
1980   }
1981 }
1982
1983 static gboolean
1984 _rtsp_media_factory_wfd_find_media_type (GstRTSPMediaFactoryWFD * factory, gchar *uri)
1985 {
1986   GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1987   GstElement *uridecode = NULL;
1988   GstElement *tmp = NULL;
1989   GstBus *bus;
1990   GMainContext *context;
1991   GSource *source;
1992
1993   priv = factory->priv;
1994
1995   context = g_main_context_new();
1996   priv->discover_loop = g_main_loop_new(context, FALSE);
1997
1998   tmp = gst_element_factory_make ("decodebin", NULL);
1999   priv->decodebin_type = G_OBJECT_TYPE (tmp);
2000   gst_object_unref (tmp);
2001
2002   /* if a URI was provided, use it instead of the default one */
2003   priv->discover_pipeline = (GstBin *) gst_pipeline_new ("Discover");
2004   uridecode = gst_element_factory_make("uridecodebin", "uri");
2005   g_object_set (G_OBJECT (uridecode), "uri", uri, NULL);
2006   gst_bin_add (priv->discover_pipeline, uridecode);
2007   if (priv->discover_pipeline == NULL || uridecode == NULL) {
2008     GST_INFO_OBJECT (factory, "Failed to create type find pipeline");
2009     type_detected = FALSE;
2010     return FALSE;
2011   }
2012
2013   /* we add a message handler */
2014   bus = gst_pipeline_get_bus (GST_PIPELINE (priv->discover_pipeline));
2015   source = gst_bus_create_watch (bus);
2016   gst_bus_add_signal_watch (bus);
2017
2018   g_source_set_callback (source, (GSourceFunc) gst_bus_async_signal_func, NULL, NULL);
2019   g_source_attach (source, context);
2020   g_signal_connect_object (bus, "message",
2021       G_CALLBACK (_rtsp_media_factory_wfd_discover_pipe_bus_call), factory, 0);
2022
2023   g_signal_connect_object (uridecode, "pad-added",
2024       G_CALLBACK (_rtsp_media_factory_wfd_discover_pad_added_cb), priv->discover_pipeline, 0);
2025   g_signal_connect_object (uridecode, "element-added",
2026             G_CALLBACK (_rtsp_media_factory_wfd_uridecodebin_element_added_cb),
2027             factory, 0);
2028   g_signal_connect_object (uridecode, "no-more-pads",
2029             G_CALLBACK (_rtsp_media_factory_wfd_uridecode_no_pad_cb), factory, 0);
2030   gst_element_set_state (GST_ELEMENT (priv->discover_pipeline), GST_STATE_PLAYING);
2031
2032   g_main_loop_run(priv->discover_loop);
2033
2034   gst_element_set_state (GST_ELEMENT (priv->discover_pipeline), GST_STATE_NULL);
2035   g_source_destroy(source);
2036   g_source_unref (source);
2037   g_main_loop_unref(priv->discover_loop);
2038   g_main_context_unref(context);
2039   gst_object_unref(bus);
2040   gst_object_unref (GST_OBJECT (priv->discover_pipeline));
2041
2042   return TRUE;
2043 }
2044
2045 gint
2046 gst_rtsp_media_factory_wfd_uri_type_find(GstRTSPMediaFactory *factory,
2047     gchar *filesrc, guint8 *detected_video_codec, guint8 *detected_audio_codec)
2048 {
2049   GstRTSPMediaFactoryWFD *_factory = GST_RTSP_MEDIA_FACTORY_WFD_CAST (factory);
2050   GstRTSPMediaFactoryWFDPrivate *priv = _factory->priv;
2051
2052   type_detected = FALSE;
2053
2054   _rtsp_media_factory_wfd_find_media_type (_factory, filesrc);
2055
2056   if (type_detected == FALSE) {
2057     GST_ERROR_OBJECT (_factory, "Media type cannot be detected");
2058     return GST_RTSP_ERROR;
2059   }
2060   GST_INFO_OBJECT (_factory, "Media type detected");
2061
2062   if (priv->res.h264_found)
2063     *detected_video_codec = GST_WFD_VIDEO_H264;
2064
2065   if (priv->res.aac_found)
2066     *detected_audio_codec = GST_WFD_AUDIO_AAC;
2067
2068   if (priv->res.ac3_found)
2069     *detected_audio_codec = GST_WFD_AUDIO_AC3;
2070
2071   return GST_RTSP_OK;
2072 }
2073
2074 gint
2075 gst_rtsp_media_factory_wfd_set_direct_streaming(GstRTSPMediaFactory * factory,
2076     gint direct_streaming, gchar *filesrc)
2077 {
2078   GstRTSPMediaFactoryWFD *_factory = GST_RTSP_MEDIA_FACTORY_WFD_CAST (factory);
2079   linked = FALSE;
2080
2081   if (direct_streaming == 0) {
2082     if (!_rtsp_media_factory_wfd_relink_pipeline(_factory)) {
2083       GST_ERROR_OBJECT (factory, "Failed to relink pipeline");
2084       return GST_RTSP_ERROR;
2085     }
2086
2087     _rtsp_media_factory_wfd_destroy_direct_pipe ((void *)_factory);
2088
2089     GST_INFO_OBJECT (_factory, "Direct streaming bin removed");
2090
2091     return GST_RTSP_OK;
2092   }
2093
2094   _factory->priv->direct_pipe = g_new0 (GstRTSPMediaWFDDirectPipelineData, 1);
2095   _factory->priv->direct_pipe->uri = g_strdup(filesrc);
2096
2097   if (!_rtsp_media_factory_wfd_create_direct_pipeline(_factory)) {
2098     GST_ERROR_OBJECT (_factory, "Direct pipeline creation failed");
2099     return GST_RTSP_ERROR;
2100   }
2101
2102   g_mutex_lock (&_factory->priv->direct_lock);
2103   while (linked != TRUE) {
2104     gint64 end_time = g_get_monotonic_time () + 5 * G_TIME_SPAN_SECOND;
2105     if (!g_cond_wait_until (&_factory->priv->direct_cond, &_factory->priv->direct_lock, end_time)) {
2106       g_mutex_unlock (&_factory->priv->direct_lock);
2107       GST_ERROR_OBJECT (_factory, "Direct pipeline linking failed");
2108       return GST_RTSP_ERROR;
2109     }
2110   }
2111   g_mutex_unlock (&_factory->priv->direct_lock);
2112
2113   GST_INFO_OBJECT (_factory, "Direct streaming bin created");
2114
2115   return GST_RTSP_OK;
2116 }