2 * Copyright (C) 2015 Samsung Electronics Hyunjun Ko <zzoon.ko@samsung.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
20 * SECTION:rtsp-media-factory
21 * @short_description: A factory for media pipelines
22 * @see_also: #GstRTSPMountPoints, #GstRTSPMedia
24 * The #GstRTSPMediaFactoryWFD is responsible for creating or recycling
25 * #GstRTSPMedia objects based on the passed URL.
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().
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
36 * Last reviewed on 2013-07-11 (1.0.0)
42 #include "rtsp-media-factory-wfd.h"
43 #include "gstwfdmessage.h"
44 #include "rtsp-media-ext.h"
46 #define GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE(obj) \
47 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTSP_MEDIA_FACTORY_WFD, GstRTSPMediaFactoryWFDPrivate))
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)))
53 typedef struct _GstRTPSMediaWFDTypeFindResult GstRTPSMediaWFDTypeFindResult;
55 struct _GstRTPSMediaWFDTypeFindResult{
59 GstElementFactory *demux_fact;
60 GstElementFactory *src_fact;
63 typedef struct _GstRTSPMediaWFDDirectPipelineData GstRTSPMediaWFDDirectPipelineData;
65 struct _GstRTSPMediaWFDDirectPipelineData {
77 struct _GstRTSPMediaFactoryWFDPrivate
80 GstRTSPPermissions *permissions;
83 GstRTSPLowerTrans protocols;
93 guint video_framerate;
94 guint video_enc_skip_inbuf_value;
95 GstElement *video_queue;
99 guint decide_udp_bitrate[21];
100 guint min_udp_bitrate;
101 guint max_udp_bitrate;
102 gboolean decided_udp_bitrate;
105 gchar *audio_encoder_aac;
106 gchar *audio_encoder_ac3;
108 guint64 audio_latency_time;
109 guint64 audio_buffer_time;
110 gboolean audio_do_timestamp;
111 guint8 audio_channels;
113 guint8 audio_bitrate;
114 GstElement *audio_queue;
115 GstBin *audio_srcbin;
119 GType decodebin_type;
120 GstBin *discover_pipeline;
121 GstRTPSMediaWFDTypeFindResult res;
122 GstRTSPMediaWFDDirectPipelineData *direct_pipe;
125 GstElement *mux_queue;
128 GMainLoop *discover_loop;
130 guint64 video_resolution_supported;
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
155 SIGNAL_MEDIA_CONSTRUCTED,
156 SIGNAL_MEDIA_CONFIGURE,
157 SIGNAL_DIRECT_STREAMING_END,
161 GST_DEBUG_CATEGORY_STATIC (rtsp_media_wfd_debug);
162 #define GST_CAT_DEFAULT rtsp_media_wfd_debug
164 static guint gst_rtsp_media_factory_wfd_signals[SIGNAL_LAST] = { 0 };
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);
171 static void gst_rtsp_media_factory_wfd_finalize (GObject * obj);
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);
179 static void _config_bitrate (GstRTSPMediaFactoryWFD * factory);
181 G_DEFINE_TYPE (GstRTSPMediaFactoryWFD, gst_rtsp_media_factory_wfd,
182 GST_TYPE_RTSP_MEDIA_FACTORY);
185 gst_rtsp_media_factory_wfd_class_init (GstRTSPMediaFactoryWFDClass * klass)
187 GObjectClass *gobject_class;
188 GstRTSPMediaFactoryClass *factory_class;
190 g_type_class_add_private (klass, sizeof (GstRTSPMediaFactoryWFDPrivate));
192 gobject_class = G_OBJECT_CLASS (klass);
193 factory_class = GST_RTSP_MEDIA_FACTORY_CLASS (klass);
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;
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);
205 factory_class->construct = rtsp_media_factory_wfd_construct;
206 factory_class->create_element = rtsp_media_factory_wfd_create_element;
208 GST_DEBUG_CATEGORY_INIT (rtsp_media_wfd_debug, "rtspmediafactorywfd", 0,
209 "GstRTSPMediaFactoryWFD");
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)
217 GstRTSPMediaFactoryWFDPrivate *priv =
218 GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE (factory);
219 factory->priv = priv;
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;
230 gst_rtsp_media_factory_wfd_set_encoders (GstRTSPMediaFactoryWFD * factory,
231 gchar * video_encoder, gchar * audio_encoder_aac, gchar * audio_encoder_ac3)
233 GstRTSPMediaFactoryWFDPrivate *priv =
234 GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE (factory);
235 factory->priv = priv;
237 priv->video_encoder = video_encoder;
238 priv->audio_encoder_aac = audio_encoder_aac;
239 priv->audio_encoder_ac3 = audio_encoder_ac3;
243 gst_rtsp_media_factory_wfd_set_dump_ts (GstRTSPMediaFactoryWFD * factory,
246 GstRTSPMediaFactoryWFDPrivate *priv =
247 GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE (factory);
248 factory->priv = priv;
250 priv->dump_ts = dump_ts;
254 gst_rtsp_media_factory_wfd_set_negotiated_resolution (GstRTSPMediaFactory *
255 factory, guint32 width, guint32 height)
257 GstRTSPMediaFactoryWFD *factory_wfd = GST_RTSP_MEDIA_FACTORY_WFD (factory);
258 GstRTSPMediaFactoryWFDPrivate *priv = factory_wfd->priv;
260 priv->video_width = width;
261 priv->video_height = height;
262 _config_bitrate (factory_wfd);
266 gst_rtsp_media_factory_wfd_set_audio_codec (GstRTSPMediaFactory * factory,
269 GstRTSPMediaFactoryWFD *factory_wfd = GST_RTSP_MEDIA_FACTORY_WFD (factory);
270 GstRTSPMediaFactoryWFDPrivate *priv = factory_wfd->priv;
272 priv->audio_codec = audio_codec;
276 gst_rtsp_media_factory_wfd_set_video_codec (GstRTSPMediaFactory * factory,
279 GstRTSPMediaFactoryWFD *factory_wfd = GST_RTSP_MEDIA_FACTORY_WFD (factory);
280 GstRTSPMediaFactoryWFDPrivate *priv = factory_wfd->priv;
282 priv->video_codec = video_codec;
286 _config_bitrate (GstRTSPMediaFactoryWFD * factory)
288 GstRTSPMediaFactoryWFDPrivate *priv = factory->priv;
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];
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];
320 gst_rtsp_media_factory_wfd_set_venc_bitrate (GstRTSPMediaFactory * factory,
323 GstRTSPMediaFactoryWFD *factory_wfd = GST_RTSP_MEDIA_FACTORY_WFD (factory);
324 GstRTSPMediaFactoryWFDPrivate *priv = factory_wfd->priv;
326 g_object_set (priv->venc, "target-bitrate", bitrate, NULL);
327 priv->video_bitrate = (guint) bitrate;
331 gst_rtsp_media_factory_wfd_get_venc_bitrate (GstRTSPMediaFactory * factory,
336 GstRTSPMediaFactoryWFD *factory_wfd = GST_RTSP_MEDIA_FACTORY_WFD (factory);
337 GstRTSPMediaFactoryWFDPrivate *priv = factory_wfd->priv;
339 g_object_get (priv->venc, "target-bitrate", &cur_bitrate, NULL);
341 if (cur_bitrate == 0) {
342 *bitrate = priv->video_bitrate;
344 *bitrate = (gint) cur_bitrate;
349 gst_rtsp_media_factory_wfd_get_config_bitrate (GstRTSPMediaFactory * factory,
350 guint32 * min, guint32 * max)
352 GstRTSPMediaFactoryWFD *factory_wfd = GST_RTSP_MEDIA_FACTORY_WFD (factory);
353 GstRTSPMediaFactoryWFDPrivate *priv = factory_wfd->priv;
355 *min = priv->min_udp_bitrate;
356 *max = priv->max_udp_bitrate;
360 gst_rtsp_media_factory_wfd_set_config_bitrate (GstRTSPMediaFactoryWFD * factory,
361 guint * config_bitrate)
363 GstRTSPMediaFactoryWFDPrivate *priv = factory->priv;
366 for (idx = 0; idx < 21; idx++) {
367 priv->decide_udp_bitrate[idx] = config_bitrate[idx];
369 priv->decided_udp_bitrate = TRUE;
371 _config_bitrate (factory);
375 gst_rtsp_media_factory_wfd_init (GstRTSPMediaFactoryWFD * factory)
377 GstRTSPMediaFactoryWFDPrivate *priv =
378 GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE (factory);
379 factory->priv = priv;
381 priv->launch = g_strdup (DEFAULT_LAUNCH);
382 priv->shared = DEFAULT_SHARED;
383 priv->protocols = DEFAULT_PROTOCOLS;
384 priv->buffer_size = DEFAULT_BUFFER_SIZE;
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;
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;
413 g_mutex_init (&priv->direct_lock);
414 g_cond_init (&priv->direct_cond);
416 priv->discover_pipeline = NULL;
417 priv->direct_pipe = NULL;
418 memset (&priv->res, 0x00, sizeof (GstRTPSMediaWFDTypeFindResult));
419 priv->stream_bin = NULL;
421 priv->mux_queue = NULL;
424 g_mutex_init (&priv->lock);
428 gst_rtsp_media_factory_wfd_finalize (GObject * obj)
430 GstRTSPMediaFactoryWFD *factory = GST_RTSP_MEDIA_FACTORY_WFD (obj);
431 GstRTSPMediaFactoryWFDPrivate *priv = factory->priv;
433 if (priv->permissions)
434 gst_rtsp_permissions_unref (priv->permissions);
435 g_free (priv->launch);
436 g_mutex_clear (&priv->lock);
438 g_mutex_clear (&priv->direct_lock);
439 g_cond_clear (&priv->direct_cond);
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);
448 if (priv->video_encoder)
449 g_free (priv->video_encoder);
451 G_OBJECT_CLASS (gst_rtsp_media_factory_wfd_parent_class)->finalize (obj);
454 GstRTSPMediaFactoryWFD *
455 gst_rtsp_media_factory_wfd_new (void)
457 GstRTSPMediaFactoryWFD *result;
459 result = g_object_new (GST_TYPE_RTSP_MEDIA_FACTORY_WFD, NULL);
465 gst_rtsp_media_factory_wfd_get_property (GObject * object,
466 guint propid, GValue * value, GParamSpec * pspec)
468 //GstRTSPMediaFactoryWFD *factory = GST_RTSP_MEDIA_FACTORY_WFD (object);
472 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
477 gst_rtsp_media_factory_wfd_set_property (GObject * object,
478 guint propid, const GValue * value, GParamSpec * pspec)
480 //GstRTSPMediaFactoryWFD *factory = GST_RTSP_MEDIA_FACTORY_WFD (object);
484 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
488 static GstPadProbeReturn
489 rtsp_media_wfd_dump_data (GstPad * pad, GstPadProbeInfo * info, gpointer u_data)
496 if (info->type == (GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_PUSH)) {
497 GstBuffer *buffer = gst_pad_probe_info_get_buffer (info);
499 gst_buffer_map (buffer, &mapinfo, GST_MAP_READ);
501 size = gst_buffer_get_size (buffer);
503 f = fopen ("/root/probe.ts", "a");
505 fwrite (data, size, 1, f);
508 gst_buffer_unmap (buffer, &mapinfo);
511 return GST_PAD_PROBE_OK;
515 _rtsp_media_factory_wfd_create_audio_capture_bin (GstRTSPMediaFactoryWFD *
516 factory, GstBin * srcbin)
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;
528 gboolean is_enc_req = TRUE;
530 gchar *acodec = NULL;
532 priv = factory->priv;
534 if (priv->audio_codec == GST_WFD_AUDIO_UNKNOWN) {
535 GST_INFO_OBJECT (factory, "Skip create audio source");
539 priv->audio_srcbin = (GstBin *)gst_bin_new ("audio");
541 /* create audio src element */
542 audiosrc = gst_element_factory_make ("pulsesrc", "audiosrc");
544 GST_ERROR_OBJECT (factory, "failed to create audiosrc element");
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);
556 audio_properties_name = gst_structure_new_from_string (priv->audio_device);
558 g_object_set (audiosrc, "stream-properties", audio_properties_name, NULL);
559 g_object_set (audiosrc, "buffer-time", (gint64) priv->audio_buffer_time,
561 g_object_set (audiosrc, "latency-time", (gint64) priv->audio_latency_time,
563 g_object_set (audiosrc, "do-timestamp", (gboolean) priv->audio_do_timestamp,
565 g_object_set (audiosrc, "provide-clock", (gboolean) FALSE, NULL);
566 g_object_set (audiosrc, "is-live", (gboolean) TRUE, NULL);
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);
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");
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);
588 acaps2 = gst_element_factory_make ("capsfilter", "audiocaps2");
589 if (NULL == acaps2) {
590 GST_ERROR_OBJECT (factory, "failed to create audio capsilfter element");
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);
601 /* create audio caps element */
602 acaps = gst_element_factory_make ("capsfilter", "audiocaps");
604 GST_ERROR_OBJECT (factory, "failed to create audio capsilfter element");
608 if (priv->audio_channels == GST_WFD_CHANNEL_2)
610 else if (priv->audio_channels == GST_WFD_CHANNEL_4)
612 else if (priv->audio_channels == GST_WFD_CHANNEL_6)
614 else if (priv->audio_channels == GST_WFD_CHANNEL_8)
619 if (priv->audio_freq == GST_WFD_FREQ_44100)
621 else if (priv->audio_freq == GST_WFD_FREQ_48000)
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);
642 if (priv->audio_codec == GST_WFD_AUDIO_AAC) {
643 acodec = g_strdup (priv->audio_encoder_aac);
645 } else if (priv->audio_codec == GST_WFD_AUDIO_AC3) {
646 acodec = g_strdup (priv->audio_encoder_ac3);
648 } else if (priv->audio_codec == GST_WFD_AUDIO_LPCM) {
649 GST_DEBUG_OBJECT (factory, "No codec required, raw data will be sent");
652 GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
657 aenc = gst_element_factory_make (acodec, "audioenc");
659 GST_ERROR_OBJECT (factory, "failed to create audio encoder element");
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);
668 aqueue = gst_element_factory_make ("queue", "audio-queue");
670 GST_ERROR_OBJECT (factory, "failed to create audio queue element");
674 gst_bin_add_many (priv->audio_srcbin, audiosrc, acaps, aenc, aqueue, NULL);
675 gst_bin_add (srcbin, GST_ELEMENT (priv->audio_srcbin));
677 if (!gst_element_link_many (audiosrc, acaps, aenc, aqueue, NULL)) {
678 GST_ERROR_OBJECT (factory, "Failed to link audio src elements...");
682 aqueue = gst_element_factory_make ("queue", "audio-queue");
684 GST_ERROR_OBJECT (factory, "failed to create audio queue element");
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));
691 if (!gst_element_link_many (audiosrc, acaps2, audio_convert, acaps, aqueue,
693 GST_ERROR_OBJECT (factory, "Failed to link audio src elements...");
698 priv->audio_queue = aqueue;
701 if (audio_properties_name)
702 gst_structure_free (audio_properties_name);
706 gst_object_unref (acaps);
707 gst_object_unref (aqueue);
710 if (audio_properties_name)
711 gst_structure_free (audio_properties_name);
716 _rtsp_media_factory_wfd_create_videotest_bin (GstRTSPMediaFactoryWFD * factory,
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;
729 priv = factory->priv;
731 GST_INFO_OBJECT (factory, "picked videotestsrc as video source");
732 priv->video_srcbin = (GstBin *)gst_bin_new ("video");
734 videosrc = gst_element_factory_make ("videotestsrc", "videosrc");
735 if (NULL == videosrc) {
736 GST_ERROR_OBJECT (factory, "failed to create ximagesrc element");
740 /* create video caps element */
741 vcaps = gst_element_factory_make ("capsfilter", "videocaps");
743 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
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),
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");
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");
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),
776 if (priv->video_codec == GST_WFD_VIDEO_H264)
777 vcodec = g_strdup (priv->video_encoder);
779 GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
783 venc = gst_element_factory_make (vcodec, "videoenc");
788 GST_ERROR_OBJECT (factory, "failed to create video encoder element");
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);
796 vparse = gst_element_factory_make ("h264parse", "videoparse");
797 if (NULL == vparse) {
798 GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
801 g_object_set (vparse, "config-interval", 1, NULL);
803 vqueue = gst_element_factory_make ("queue", "video-queue");
805 GST_ERROR_OBJECT (factory, "failed to create video queue element");
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...");
817 priv->video_queue = vqueue;
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);
834 _rtsp_media_factory_wfd_create_waylandsrc_bin (GstRTSPMediaFactoryWFD * factory,
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;
845 priv = factory->priv;
847 GST_INFO_OBJECT (factory, "picked waylandsrc as video source");
849 if (priv->video_codec == GST_WFD_VIDEO_UNKNOWN) {
850 GST_INFO_OBJECT (factory, "Skip create video source.");
854 priv->video_srcbin = (GstBin *)gst_bin_new ("video");
856 videosrc = gst_element_factory_make ("waylandsrc", "videosrc");
857 if (NULL == videosrc) {
858 GST_ERROR_OBJECT (factory, "failed to create ximagesrc element");
862 /* create video caps element */
863 vcaps = gst_element_factory_make ("capsfilter", "videocaps");
865 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
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),
877 if (priv->video_codec == GST_WFD_VIDEO_H264)
878 vcodec = g_strdup (priv->video_encoder);
880 GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
884 venc = gst_element_factory_make (vcodec, "videoenc");
889 GST_ERROR_OBJECT (factory, "failed to create video encoder element");
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);
898 vparse = gst_element_factory_make ("h264parse", "videoparse");
899 if (NULL == vparse) {
900 GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
903 g_object_set (vparse, "config-interval", 1, NULL);
905 vqueue = gst_element_factory_make ("queue", "video-queue");
907 GST_ERROR_OBJECT (factory, "failed to create video queue element");
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...");
918 priv->video_queue = vqueue;
924 gst_object_unref (videosrc);
925 gst_object_unref (vqueue);
930 _rtsp_media_factory_wfd_create_camera_capture_bin (GstRTSPMediaFactoryWFD *
931 factory, GstBin * srcbin)
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;
941 priv = factory->priv;
942 priv->video_srcbin = (GstBin *)gst_bin_new ("video");
944 videosrc = gst_element_factory_make ("camerasrc", "videosrc");
945 if (NULL == videosrc) {
946 GST_ERROR_OBJECT (factory, "failed to create camerasrc element");
950 /* create video caps element */
951 vcaps = gst_element_factory_make ("capsfilter", "videocaps");
953 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
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),
966 if (priv->video_codec == GST_WFD_VIDEO_H264)
967 vcodec = g_strdup (priv->video_encoder);
969 GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
973 venc = gst_element_factory_make (vcodec, "videoenc");
978 GST_ERROR_OBJECT (factory, "failed to create video encoder element");
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);
986 vparse = gst_element_factory_make ("h264parse", "videoparse");
987 if (NULL == vparse) {
988 GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
991 g_object_set (vparse, "config-interval", 1, NULL);
993 vqueue = gst_element_factory_make ("queue", "video-queue");
995 GST_ERROR_OBJECT (factory, "failed to create video queue element");
999 gst_bin_add_many (priv->video_srcbin, videosrc, vcaps, venc, vparse, vqueue, NULL);
1000 gst_bin_add (srcbin, GST_ELEMENT (priv->video_srcbin));
1002 if (!gst_element_link_many (videosrc, vcaps, venc, vparse, vqueue, NULL)) {
1003 GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
1007 priv->video_queue = vqueue;
1013 gst_object_unref (videosrc);
1014 gst_object_unref (vqueue);
1019 _rtsp_media_factory_wfd_create_xcapture_bin (GstRTSPMediaFactoryWFD * factory,
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;
1032 priv = factory->priv;
1034 GST_INFO_OBJECT (factory, "picked ximagesrc as video source");
1035 priv->video_srcbin = (GstBin *)gst_bin_new ("video");
1037 videosrc = gst_element_factory_make ("ximagesrc", "videosrc");
1038 if (NULL == videosrc) {
1039 GST_ERROR_OBJECT (factory, "failed to create ximagesrc element");
1043 videoscale = gst_element_factory_make ("videoscale", "videoscale");
1044 if (NULL == videoscale) {
1045 GST_ERROR_OBJECT (factory, "failed to create videoscale element");
1049 videoconvert = gst_element_factory_make ("videoconvert", "videoconvert");
1050 if (NULL == videoconvert) {
1051 GST_ERROR_OBJECT (factory, "failed to create videoconvert element");
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");
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),
1069 if (priv->video_codec == GST_WFD_VIDEO_H264)
1070 vcodec = g_strdup (priv->video_encoder);
1072 GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
1076 venc = gst_element_factory_make (vcodec, "videoenc");
1081 GST_ERROR_OBJECT (factory, "failed to create video encoder element");
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);
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");
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);
1099 vparse = gst_element_factory_make ("h264parse", "videoparse");
1100 if (NULL == vparse) {
1101 GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
1104 g_object_set (vparse, "config-interval", 1, NULL);
1106 vqueue = gst_element_factory_make ("queue", "video-queue");
1108 GST_ERROR_OBJECT (factory, "failed to create video queue element");
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...");
1121 priv->video_queue = vqueue;
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);
1139 _rtsp_media_factory_wfd_create_xvcapture_bin (GstRTSPMediaFactoryWFD * factory,
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;
1150 priv = factory->priv;
1152 GST_INFO_OBJECT (factory, "picked xvimagesrc as video source");
1153 priv->video_srcbin = (GstBin *)gst_bin_new ("video");
1155 videosrc = gst_element_factory_make ("xvimagesrc", "videosrc");
1156 if (NULL == videosrc) {
1157 GST_ERROR_OBJECT (factory, "failed to create xvimagesrc element");
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");
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),
1176 if (priv->video_codec == GST_WFD_VIDEO_H264) {
1177 vcodec = g_strdup (priv->video_encoder);
1179 GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
1183 venc = gst_element_factory_make (vcodec, "videoenc");
1185 GST_ERROR_OBJECT (factory, "failed to create video encoder element");
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);
1194 vparse = gst_element_factory_make ("h264parse", "videoparse");
1195 if (NULL == vparse) {
1196 GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
1199 g_object_set (vparse, "config-interval", 1, NULL);
1201 vqueue = gst_element_factory_make ("queue", "video-queue");
1203 GST_ERROR_OBJECT (factory, "failed to create video queue element");
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...");
1214 priv->video_queue = vqueue;
1222 gst_object_unref (videosrc);
1223 gst_object_unref (vqueue);
1230 _rtsp_media_factory_wfd_create_srcbin (GstRTSPMediaFactoryWFD * factory)
1232 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
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;
1243 priv = factory->priv;
1245 /* create source bin */
1246 srcbin = GST_BIN (gst_bin_new ("srcbin"));
1248 GST_ERROR_OBJECT (factory, "failed to create source bin...");
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...");
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...");
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...");
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...");
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...");
1286 GST_ERROR_OBJECT (factory, "unknow mode selected...");
1290 mux = gst_element_factory_make ("mpegtsmux", "tsmux");
1292 GST_ERROR_OBJECT (factory, "failed to create muxer element");
1296 g_object_set (mux, "wfd-mode", TRUE, NULL);
1298 mux_queue = gst_element_factory_make ("queue", "muxer-queue");
1300 GST_ERROR_OBJECT (factory, "failed to create muxer-queue element");
1304 g_object_set (mux_queue, "max-size-buffers", 20000, NULL);
1306 payload = gst_element_factory_make ("rtpmp2tpay", "pay0");
1308 GST_ERROR_OBJECT (factory, "failed to create payload element");
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);
1316 gst_bin_add_many (srcbin, mux, mux_queue, payload, NULL);
1318 if (!gst_element_link_many (mux, mux_queue, payload, NULL)) {
1319 GST_ERROR_OBJECT (factory, "Failed to link muxer & payload...");
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...");
1331 /* request srcpad from video queue */
1332 srcpad = gst_element_get_static_pad (priv->video_queue, "src");
1334 GST_ERROR_OBJECT (factory, "Failed to get srcpad from video queue...");
1337 ghost_pad = gst_ghost_pad_new ("video_src", srcpad);
1338 gst_element_add_pad (GST_ELEMENT (priv->video_srcbin), ghost_pad);
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...");
1346 gst_object_unref (mux_vsinkpad);
1347 gst_object_unref (srcpad);
1352 GST_INFO_OBJECT (factory, "Check audio codec... %d", priv->audio_codec);
1354 /* create audio source elements & add to pipeline */
1355 if (!_rtsp_media_factory_wfd_create_audio_capture_bin (factory, srcbin))
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...");
1366 /* request srcpad from audio queue */
1367 srcpad = gst_element_get_static_pad (priv->audio_queue, "src");
1369 GST_ERROR_OBJECT (factory, "Failed to get srcpad from audio queue...");
1372 ghost_pad = gst_ghost_pad_new ("audio_src", srcpad);
1373 gst_element_add_pad (GST_ELEMENT (priv->audio_srcbin), ghost_pad);
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...");
1381 gst_object_unref (mux_asinkpad);
1382 gst_object_unref (srcpad);
1387 GstPad *pad_probe = NULL;
1388 pad_probe = gst_element_get_static_pad (mux, "src");
1390 if (NULL == pad_probe) {
1391 GST_INFO_OBJECT (factory, "pad for probe not created");
1393 GST_INFO_OBJECT (factory, "pad for probe SUCCESSFUL");
1395 gst_pad_add_probe (pad_probe, GST_PAD_PROBE_TYPE_BUFFER,
1396 rtsp_media_wfd_dump_data, factory, NULL);
1398 gst_object_unref (pad_probe);
1401 GST_DEBUG_OBJECT (factory, "successfully created source bin...");
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);
1408 return GST_ELEMENT_CAST (srcbin);
1411 GST_ERROR_OBJECT (factory, "Failed to create pipeline");
1413 gst_object_unref (mux_vsinkpad);
1415 gst_object_unref (mux_asinkpad);
1417 gst_object_unref (srcpad);
1419 gst_object_unref (srcbin);
1424 rtsp_media_factory_wfd_create_element (GstRTSPMediaFactory * factory,
1425 const GstRTSPUrl * url)
1427 GstRTSPMediaFactoryWFD *_factory = GST_RTSP_MEDIA_FACTORY_WFD_CAST (factory);
1428 GstElement *element = NULL;
1430 GST_RTSP_MEDIA_FACTORY_WFD_LOCK (factory);
1432 element = _rtsp_media_factory_wfd_create_srcbin (_factory);
1434 GST_RTSP_MEDIA_FACTORY_WFD_UNLOCK (factory);
1439 static GstRTSPMedia *
1440 rtsp_media_factory_wfd_construct (GstRTSPMediaFactory * factory,
1441 const GstRTSPUrl * url)
1443 GstRTSPMedia *media;
1444 GstElement *element, *pipeline;
1445 GstRTSPMediaFactoryClass *klass;
1447 klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
1449 if (!klass->create_pipeline)
1452 element = gst_rtsp_media_factory_create_element (factory, url);
1453 if (element == NULL)
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);
1460 gst_rtsp_media_collect_streams (media);
1462 pipeline = klass->create_pipeline (factory, media);
1463 if (pipeline == NULL)
1471 g_critical ("no create_pipeline function");
1476 g_critical ("could not create element");
1481 g_critical ("can't create pipeline");
1482 g_object_unref (media);
1487 gint type_detected = FALSE;
1488 gint linked = FALSE;
1489 static gint in_pad_probe;
1491 static GstPadProbeReturn
1492 _rtsp_media_factory_wfd_restore_pipe_probe_cb (GstPad *pad, GstPadProbeInfo *info, gpointer user_data)
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;
1502 if (!g_atomic_int_compare_and_exchange (&in_pad_probe, FALSE, TRUE))
1503 return GST_PAD_PROBE_OK;
1505 factory = (GstRTSPMediaFactoryWFD *) user_data;
1506 priv = factory->priv;
1507 pipe_data = priv->direct_pipe;
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));
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);
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);
1524 gst_pad_link (new_src, sink);
1525 gst_object_unref (new_src);
1526 gst_object_unref (old_sink);
1528 gst_element_set_state (GST_ELEMENT(pipe_data->pipeline), GST_STATE_PAUSED);
1530 /* signal that new pipeline linked */
1531 g_mutex_lock (&priv->direct_lock);
1532 g_cond_signal (&priv->direct_cond);
1534 g_mutex_unlock (&priv->direct_lock);
1536 return GST_PAD_PROBE_REMOVE;
1540 _rtsp_media_factory_wfd_destroy_direct_pipe(void *user_data)
1542 GstRTSPMediaFactoryWFD *factory = NULL;
1543 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1544 GstRTSPMediaWFDDirectPipelineData *pipe_data = NULL;
1546 factory = (GstRTSPMediaFactoryWFD *) user_data;
1547 priv = factory->priv;
1548 pipe_data = priv->direct_pipe;
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));
1554 g_signal_emit (factory,
1555 gst_rtsp_media_factory_wfd_signals[SIGNAL_DIRECT_STREAMING_END], 0, NULL);
1560 _rtsp_media_factory_wfd_demux_pad_added_cb (GstElement *element,
1564 GstPad *sinkpad = NULL;
1565 GstRTSPMediaFactoryWFD *factory = NULL;
1566 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1567 GstRTSPMediaWFDDirectPipelineData *pipe_data = NULL;
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);
1574 factory = (GstRTSPMediaFactoryWFD *) data;
1575 priv = factory->priv;
1576 pipe_data = priv->direct_pipe;
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);
1584 GST_DEBUG_OBJECT (factory, "pad linked");
1587 if (gst_pad_link (pad, sinkpad) != GST_PAD_LINK_OK)
1588 GST_DEBUG_OBJECT (factory, "can't link demux %s pad", pad_name);
1590 gst_object_unref (sinkpad);
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);
1599 gst_object_unref (sinkpad);
1608 static GstPadProbeReturn
1609 _rtsp_media_factory_wfd_pay_pad_probe_cb (GstPad *pad, GstPadProbeInfo *info, gpointer user_data)
1611 GstPad *old_src = NULL;
1612 GstPad *sink = NULL;
1613 GstPad *old_sink = NULL;
1614 GstPad *new_src = NULL;
1615 GstPad *fas_sink = NULL;
1617 GstRTSPMediaFactoryWFD *factory = NULL;
1618 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1619 GstRTSPMediaWFDDirectPipelineData *pipe_data = NULL;
1621 if (!g_atomic_int_compare_and_exchange (&in_pad_probe, FALSE, TRUE))
1622 return GST_PAD_PROBE_OK;
1624 factory = (GstRTSPMediaFactoryWFD *) user_data;
1625 priv = factory->priv;
1626 pipe_data = priv->direct_pipe;
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);
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);
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);
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);
1657 /* signal that new pipeline linked */
1658 g_mutex_lock (&priv->direct_lock);
1660 g_cond_signal (&priv->direct_cond);
1661 g_mutex_unlock (&priv->direct_lock);
1663 return GST_PAD_PROBE_REMOVE;
1667 _rtsp_media_factory_wfd_relink_pipeline(GstRTSPMediaFactoryWFD * factory)
1669 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1670 GstPad *probe_pad = NULL;
1671 gint64 end_time = 0;
1673 priv = factory->priv;
1675 probe_pad = gst_element_get_static_pad (priv->pay, "sink");
1676 if (probe_pad == NULL)
1679 in_pad_probe = FALSE;
1681 gst_pad_add_probe (probe_pad, GST_PAD_PROBE_TYPE_IDLE, _rtsp_media_factory_wfd_restore_pipe_probe_cb, factory, NULL);
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");
1690 g_mutex_unlock (&factory->priv->direct_lock);
1695 static GstPadProbeReturn
1696 _rtsp_media_factory_wfd_src_pad_probe_cb(GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1698 GstRTSPMediaFactoryWFD *factory = NULL;
1699 GstEvent *event = GST_PAD_PROBE_INFO_EVENT(info);
1701 factory = (GstRTSPMediaFactoryWFD *) user_data;
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));
1706 info->data = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, gst_structure_new_empty ("fillEOS"));
1708 if (!_rtsp_media_factory_wfd_relink_pipeline(factory)) {
1709 GST_ERROR_OBJECT (factory, "Failed to relink pipeline");
1710 return GST_PAD_PROBE_REMOVE;
1713 g_idle_add((GSourceFunc)_rtsp_media_factory_wfd_destroy_direct_pipe, factory);
1714 return GST_PAD_PROBE_REMOVE;
1717 return GST_PAD_PROBE_OK;
1721 _rtsp_media_factory_wfd_create_direct_pipeline(GstRTSPMediaFactoryWFD * factory)
1723 GstElement *src = NULL;
1724 GstElement *demux = NULL;
1726 GstPad *srcpad = NULL;
1727 GstPad *mux_vsinkpad = NULL;
1728 GstPad *mux_asinkpad = NULL;
1729 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1730 GstRTSPMediaWFDDirectPipelineData *pipe_data = NULL;
1732 priv = factory->priv;
1733 pipe_data = priv->direct_pipe;
1735 pipe_data->pipeline = (GstBin *) gst_bin_new ("direct");
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);
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");
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);
1757 GST_ERROR_OBJECT(factory, "No file path");
1760 g_object_set (src, "location", path, NULL);
1763 g_object_set (src, "uri", pipe_data->uri, NULL);
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);
1769 if (!gst_element_link (src, demux)) {
1770 GST_ERROR_OBJECT (factory, "Can't link src with demux");
1774 if (!gst_element_link (pipe_data->ap, pipe_data->aq)) {
1775 GST_ERROR_OBJECT (factory, "Can't link audio parse and queue");
1779 if (!gst_element_link (pipe_data->vp, pipe_data->vq)) {
1780 GST_ERROR_OBJECT (factory, "Can't link video parse and queue");
1784 if (!gst_element_link (pipe_data->tsmux, pipe_data->mux_fs)) {
1785 GST_DEBUG_OBJECT (factory, "Can't link muxer and fakesink");
1789 g_signal_connect_object (demux, "pad-added", G_CALLBACK (_rtsp_media_factory_wfd_demux_pad_added_cb), factory, 0);
1791 gst_bin_add (priv->stream_bin, GST_ELEMENT (pipe_data->pipeline));
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...");
1801 /* request srcpad from video queue */
1802 srcpad = gst_element_get_static_pad (pipe_data->vq, "src");
1804 GST_ERROR_OBJECT (factory, "Failed to get srcpad from video queue...");
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...");
1812 gst_object_unref (mux_vsinkpad);
1813 gst_object_unref (srcpad);
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...");
1823 /* request srcpad from audio queue */
1824 srcpad = gst_element_get_static_pad (pipe_data->aq, "src");
1826 GST_ERROR_OBJECT (factory, "Failed to get srcpad from audio queue...");
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...");
1835 gst_object_unref (mux_asinkpad);
1836 gst_object_unref (srcpad);
1839 gst_element_sync_state_with_parent (GST_ELEMENT (pipe_data->pipeline));
1841 srcpad = gst_element_get_static_pad (priv->pay, "sink");
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);
1851 _rtsp_media_factory_wfd_decodebin_element_added_cb (GstElement *decodebin,
1852 GstElement *child, void *user_data)
1854 gchar *elem_name = g_ascii_strdown(g_type_name(G_OBJECT_TYPE(child)), -1);
1855 GstRTSPMediaFactoryWFD *factory = NULL;
1856 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1858 factory = (GstRTSPMediaFactoryWFD *) user_data;
1859 priv = factory->priv;
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);
1872 _rtsp_media_factory_wfd_uridecodebin_element_added_cb (GstElement *uridecodebin,
1873 GstElement *child, void *user_data)
1875 GstRTSPMediaFactoryWFD *factory = NULL;
1876 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1878 factory = (GstRTSPMediaFactoryWFD *) user_data;
1879 priv = factory->priv;
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);
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);
1890 _rtsp_media_factory_wfd_discover_pad_added_cb (GstElement *uridecodebin, GstPad *pad,
1893 GstPad *sinkpad = NULL;
1896 GstElement *queue = gst_element_factory_make ("queue", NULL);
1897 GstElement *sink = gst_element_factory_make ("fakesink", NULL);
1899 if (G_UNLIKELY (queue == NULL || sink == NULL))
1902 g_object_set (sink, "silent", TRUE, NULL);
1903 g_object_set (queue, "max-size-buffers", 1, "silent", TRUE, NULL);
1905 caps = gst_pad_query_caps (pad, NULL);
1907 sinkpad = gst_element_get_static_pad (queue, "sink");
1908 if (sinkpad == NULL)
1911 gst_caps_unref (caps);
1913 gst_bin_add_many (pipeline, queue, sink, NULL);
1915 if (!gst_element_link_pads_full (queue, "src", sink, "sink",
1916 GST_PAD_LINK_CHECK_NOTHING))
1918 if (!gst_element_sync_state_with_parent (sink))
1920 if (!gst_element_sync_state_with_parent (queue))
1923 if (gst_pad_link_full (pad, sinkpad,
1924 GST_PAD_LINK_CHECK_NOTHING) != GST_PAD_LINK_OK)
1926 gst_object_unref (sinkpad);
1932 gst_object_unref (sinkpad);
1934 gst_object_unref (queue);
1936 gst_object_unref (sink);
1941 _rtsp_media_factory_wfd_uridecode_no_pad_cb (GstElement * uridecodebin, void * user_data)
1943 GstRTSPMediaFactoryWFD *factory = NULL;
1944 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1946 factory = (GstRTSPMediaFactoryWFD *) user_data;
1947 priv = factory->priv;
1948 type_detected = TRUE;
1949 g_main_loop_quit (priv->discover_loop);
1953 _rtsp_media_factory_wfd_discover_pipe_bus_call (GstBus *bus,
1957 GstRTSPMediaFactoryWFD *factory = NULL;
1958 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1960 factory = (GstRTSPMediaFactoryWFD *) data;
1961 priv = factory->priv;
1963 switch (GST_MESSAGE_TYPE (msg)) {
1964 case GST_MESSAGE_ERROR: {
1968 gst_message_parse_error (msg, &error, &debug);
1971 GST_ERROR_OBJECT (factory, "Error: %s", error->message);
1972 g_error_free (error);
1974 type_detected = FALSE;
1975 g_main_loop_quit (priv->discover_loop);
1984 _rtsp_media_factory_wfd_find_media_type (GstRTSPMediaFactoryWFD * factory, gchar *uri)
1986 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1987 GstElement *uridecode = NULL;
1988 GstElement *tmp = NULL;
1990 GMainContext *context;
1993 priv = factory->priv;
1995 context = g_main_context_new();
1996 priv->discover_loop = g_main_loop_new(context, FALSE);
1998 tmp = gst_element_factory_make ("decodebin", NULL);
1999 priv->decodebin_type = G_OBJECT_TYPE (tmp);
2000 gst_object_unref (tmp);
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;
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);
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);
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),
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);
2032 g_main_loop_run(priv->discover_loop);
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));
2046 gst_rtsp_media_factory_wfd_uri_type_find(GstRTSPMediaFactory *factory,
2047 gchar *filesrc, guint8 *detected_video_codec, guint8 *detected_audio_codec)
2049 GstRTSPMediaFactoryWFD *_factory = GST_RTSP_MEDIA_FACTORY_WFD_CAST (factory);
2050 GstRTSPMediaFactoryWFDPrivate *priv = _factory->priv;
2052 type_detected = FALSE;
2054 _rtsp_media_factory_wfd_find_media_type (_factory, filesrc);
2056 if (type_detected == FALSE) {
2057 GST_ERROR_OBJECT (_factory, "Media type cannot be detected");
2058 return GST_RTSP_ERROR;
2060 GST_INFO_OBJECT (_factory, "Media type detected");
2062 if (priv->res.h264_found)
2063 *detected_video_codec = GST_WFD_VIDEO_H264;
2065 if (priv->res.aac_found)
2066 *detected_audio_codec = GST_WFD_AUDIO_AAC;
2068 if (priv->res.ac3_found)
2069 *detected_audio_codec = GST_WFD_AUDIO_AC3;
2075 gst_rtsp_media_factory_wfd_set_direct_streaming(GstRTSPMediaFactory * factory,
2076 gint direct_streaming, gchar *filesrc)
2078 GstRTSPMediaFactoryWFD *_factory = GST_RTSP_MEDIA_FACTORY_WFD_CAST (factory);
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;
2087 _rtsp_media_factory_wfd_destroy_direct_pipe ((void *)_factory);
2089 GST_INFO_OBJECT (_factory, "Direct streaming bin removed");
2094 _factory->priv->direct_pipe = g_new0 (GstRTSPMediaWFDDirectPipelineData, 1);
2095 _factory->priv->direct_pipe->uri = g_strdup(filesrc);
2097 if (!_rtsp_media_factory_wfd_create_direct_pipeline(_factory)) {
2098 GST_ERROR_OBJECT (_factory, "Direct pipeline creation failed");
2099 return GST_RTSP_ERROR;
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;
2111 g_mutex_unlock (&_factory->priv->direct_lock);
2113 GST_INFO_OBJECT (_factory, "Direct streaming bin created");