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)
46 #include "rtsp-media-factory-wfd.h"
47 #include "gstwfdmessage.h"
48 #include "rtsp-media-ext.h"
50 #define GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE(obj) \
51 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTSP_MEDIA_FACTORY_WFD, GstRTSPMediaFactoryWFDPrivate))
53 #define GST_RTSP_MEDIA_FACTORY_WFD_GET_LOCK(f) (&(GST_RTSP_MEDIA_FACTORY_WFD_CAST(f)->priv->lock))
54 #define GST_RTSP_MEDIA_FACTORY_WFD_LOCK(f) (g_mutex_lock(GST_RTSP_MEDIA_FACTORY_WFD_GET_LOCK(f)))
55 #define GST_RTSP_MEDIA_FACTORY_WFD_UNLOCK(f) (g_mutex_unlock(GST_RTSP_MEDIA_FACTORY_WFD_GET_LOCK(f)))
57 typedef struct _GstRTPSMediaWFDTypeFindResult GstRTPSMediaWFDTypeFindResult;
59 struct _GstRTPSMediaWFDTypeFindResult{
63 GstElementFactory *demux_fact;
64 GstElementFactory *src_fact;
67 typedef struct _GstRTSPMediaWFDDirectPipelineData GstRTSPMediaWFDDirectPipelineData;
69 struct _GstRTSPMediaWFDDirectPipelineData {
81 struct _GstRTSPMediaFactoryWFDPrivate
84 GstRTSPPermissions *permissions;
87 GstRTSPLowerTrans protocols;
97 guint video_framerate;
98 guint video_enc_skip_inbuf_value;
99 GstElement *video_queue;
100 GstBin *video_srcbin;
103 guint decide_udp_bitrate[21];
104 guint min_udp_bitrate;
105 guint max_udp_bitrate;
106 gboolean decided_udp_bitrate;
109 gchar *audio_encoder_aac;
110 gchar *audio_encoder_ac3;
112 guint64 audio_latency_time;
113 guint64 audio_buffer_time;
114 gboolean audio_do_timestamp;
115 guint8 audio_channels;
117 guint8 audio_bitrate;
118 GstElement *audio_queue;
119 GstBin *audio_srcbin;
123 GType decodebin_type;
124 GstBin *discover_pipeline;
125 GstRTPSMediaWFDTypeFindResult res;
126 GstRTSPMediaWFDDirectPipelineData *direct_pipe;
129 GstElement *mux_queue;
132 GMainLoop *discover_loop;
134 guint64 video_resolution_supported;
139 #define DEFAULT_LAUNCH NULL
140 #define DEFAULT_SHARED FALSE
141 #define DEFAULT_PROTOCOLS GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_UDP_MCAST | \
142 GST_RTSP_LOWER_TRANS_TCP
143 #define DEFAULT_BUFFER_SIZE 0x80000
159 SIGNAL_MEDIA_CONSTRUCTED,
160 SIGNAL_MEDIA_CONFIGURE,
161 SIGNAL_DIRECT_STREAMING_END,
165 GST_DEBUG_CATEGORY_STATIC (rtsp_media_wfd_debug);
166 #define GST_CAT_DEFAULT rtsp_media_wfd_debug
168 static guint gst_rtsp_media_factory_wfd_signals[SIGNAL_LAST] = { 0 };
170 static void gst_rtsp_media_factory_wfd_get_property (GObject * object,
171 guint propid, GValue * value, GParamSpec * pspec);
172 static void gst_rtsp_media_factory_wfd_set_property (GObject * object,
173 guint propid, const GValue * value, GParamSpec * pspec);
175 static void gst_rtsp_media_factory_wfd_finalize (GObject * obj);
178 static GstElement *rtsp_media_factory_wfd_create_element (GstRTSPMediaFactory *
179 factory, const GstRTSPUrl * url);
180 static GstRTSPMedia *rtsp_media_factory_wfd_construct (GstRTSPMediaFactory *
181 factory, const GstRTSPUrl * url);
183 static void _config_bitrate (GstRTSPMediaFactoryWFD * factory);
185 G_DEFINE_TYPE (GstRTSPMediaFactoryWFD, gst_rtsp_media_factory_wfd,
186 GST_TYPE_RTSP_MEDIA_FACTORY);
189 gst_rtsp_media_factory_wfd_class_init (GstRTSPMediaFactoryWFDClass * klass)
191 GObjectClass *gobject_class;
192 GstRTSPMediaFactoryClass *factory_class;
194 g_type_class_add_private (klass, sizeof (GstRTSPMediaFactoryWFDPrivate));
196 gobject_class = G_OBJECT_CLASS (klass);
197 factory_class = GST_RTSP_MEDIA_FACTORY_CLASS (klass);
199 gobject_class->get_property = gst_rtsp_media_factory_wfd_get_property;
200 gobject_class->set_property = gst_rtsp_media_factory_wfd_set_property;
201 gobject_class->finalize = gst_rtsp_media_factory_wfd_finalize;
203 gst_rtsp_media_factory_wfd_signals[SIGNAL_DIRECT_STREAMING_END] =
204 g_signal_new ("direct-stream-end", G_TYPE_FROM_CLASS (klass),
205 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPMediaFactoryWFDClass,
206 direct_stream_end), NULL, NULL, g_cclosure_marshal_generic,
207 G_TYPE_NONE, 0, G_TYPE_NONE);
209 factory_class->construct = rtsp_media_factory_wfd_construct;
210 factory_class->create_element = rtsp_media_factory_wfd_create_element;
212 GST_DEBUG_CATEGORY_INIT (rtsp_media_wfd_debug, "rtspmediafactorywfd", 0,
213 "GstRTSPMediaFactoryWFD");
217 gst_rtsp_media_factory_wfd_set (GstRTSPMediaFactoryWFD * factory,
218 guint8 videosrc_type, gchar * audio_device, guint64 audio_latency_time,
219 guint64 audio_buffer_time, gboolean audio_do_timestamp, guint mtu_size)
221 GstRTSPMediaFactoryWFDPrivate *priv =
222 GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE (factory);
223 factory->priv = priv;
225 priv->videosrc_type = videosrc_type;
226 priv->audio_device = audio_device;
227 priv->audio_latency_time = audio_latency_time;
228 priv->audio_buffer_time = audio_buffer_time;
229 priv->audio_do_timestamp = audio_do_timestamp;
230 priv->mtu_size = mtu_size;
234 gst_rtsp_media_factory_wfd_set_encoders (GstRTSPMediaFactoryWFD * factory,
235 gchar * video_encoder, gchar * audio_encoder_aac, gchar * audio_encoder_ac3)
237 GstRTSPMediaFactoryWFDPrivate *priv =
238 GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE (factory);
239 factory->priv = priv;
241 priv->video_encoder = video_encoder;
242 priv->audio_encoder_aac = audio_encoder_aac;
243 priv->audio_encoder_ac3 = audio_encoder_ac3;
247 gst_rtsp_media_factory_wfd_set_dump_ts (GstRTSPMediaFactoryWFD * factory,
250 GstRTSPMediaFactoryWFDPrivate *priv =
251 GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE (factory);
252 factory->priv = priv;
254 priv->dump_ts = dump_ts;
258 gst_rtsp_media_factory_wfd_set_negotiated_resolution (GstRTSPMediaFactory *
259 factory, guint32 width, guint32 height)
261 GstRTSPMediaFactoryWFD *factory_wfd = GST_RTSP_MEDIA_FACTORY_WFD (factory);
262 GstRTSPMediaFactoryWFDPrivate *priv = factory_wfd->priv;
264 priv->video_width = width;
265 priv->video_height = height;
266 _config_bitrate (factory_wfd);
270 gst_rtsp_media_factory_wfd_set_audio_codec (GstRTSPMediaFactory * factory,
273 GstRTSPMediaFactoryWFD *factory_wfd = GST_RTSP_MEDIA_FACTORY_WFD (factory);
274 GstRTSPMediaFactoryWFDPrivate *priv = factory_wfd->priv;
276 priv->audio_codec = audio_codec;
280 gst_rtsp_media_factory_wfd_set_video_codec (GstRTSPMediaFactory * factory,
283 GstRTSPMediaFactoryWFD *factory_wfd = GST_RTSP_MEDIA_FACTORY_WFD (factory);
284 GstRTSPMediaFactoryWFDPrivate *priv = factory_wfd->priv;
286 priv->video_codec = video_codec;
290 _config_bitrate (GstRTSPMediaFactoryWFD * factory)
292 GstRTSPMediaFactoryWFDPrivate *priv = factory->priv;
294 if (priv->decided_udp_bitrate) {
295 priv->video_bitrate = priv->decide_udp_bitrate[0];
296 priv->min_udp_bitrate = priv->decide_udp_bitrate[1];
297 priv->max_udp_bitrate = priv->decide_udp_bitrate[2];
299 if ((priv->video_width * priv->video_height) >= (1920 * 1080)) {
300 priv->video_bitrate = priv->decide_udp_bitrate[3];
301 priv->min_udp_bitrate = priv->decide_udp_bitrate[4];
302 priv->max_udp_bitrate = priv->decide_udp_bitrate[5];
303 } else if ((priv->video_width * priv->video_height) >= (1280 * 720)) {
304 priv->video_bitrate = priv->decide_udp_bitrate[6];
305 priv->min_udp_bitrate = priv->decide_udp_bitrate[7];
306 priv->max_udp_bitrate = priv->decide_udp_bitrate[8];
307 } else if ((priv->video_width * priv->video_height) >= (960 * 540)) {
308 priv->video_bitrate = priv->decide_udp_bitrate[9];
309 priv->min_udp_bitrate = priv->decide_udp_bitrate[10];
310 priv->max_udp_bitrate = priv->decide_udp_bitrate[11];
311 } else if ((priv->video_width * priv->video_height) >= (854 * 480)) {
312 priv->video_bitrate = priv->decide_udp_bitrate[12];
313 priv->min_udp_bitrate = priv->decide_udp_bitrate[13];
314 priv->max_udp_bitrate = priv->decide_udp_bitrate[14];
315 } else if ((priv->video_width * priv->video_height) >= (640 * 480)) {
316 priv->video_bitrate = priv->decide_udp_bitrate[15];
317 priv->min_udp_bitrate = priv->decide_udp_bitrate[16];
318 priv->max_udp_bitrate = priv->decide_udp_bitrate[17];
324 gst_rtsp_media_factory_wfd_set_venc_bitrate (GstRTSPMediaFactory * factory,
327 GstRTSPMediaFactoryWFD *factory_wfd = GST_RTSP_MEDIA_FACTORY_WFD (factory);
328 GstRTSPMediaFactoryWFDPrivate *priv = factory_wfd->priv;
330 g_object_set (priv->venc, "target-bitrate", bitrate, NULL);
331 priv->video_bitrate = (guint) bitrate;
335 gst_rtsp_media_factory_wfd_get_venc_bitrate (GstRTSPMediaFactory * factory,
340 GstRTSPMediaFactoryWFD *factory_wfd = GST_RTSP_MEDIA_FACTORY_WFD (factory);
341 GstRTSPMediaFactoryWFDPrivate *priv = factory_wfd->priv;
343 g_object_get (priv->venc, "target-bitrate", &cur_bitrate, NULL);
345 if (cur_bitrate == 0) {
346 *bitrate = priv->video_bitrate;
348 *bitrate = (gint) cur_bitrate;
353 gst_rtsp_media_factory_wfd_get_config_bitrate (GstRTSPMediaFactory * factory,
354 guint32 * min, guint32 * max)
356 GstRTSPMediaFactoryWFD *factory_wfd = GST_RTSP_MEDIA_FACTORY_WFD (factory);
357 GstRTSPMediaFactoryWFDPrivate *priv = factory_wfd->priv;
359 *min = priv->min_udp_bitrate;
360 *max = priv->max_udp_bitrate;
364 gst_rtsp_media_factory_wfd_set_config_bitrate (GstRTSPMediaFactoryWFD * factory,
365 guint * config_bitrate)
367 GstRTSPMediaFactoryWFDPrivate *priv = factory->priv;
370 for (idx = 0; idx < 21; idx++) {
371 priv->decide_udp_bitrate[idx] = config_bitrate[idx];
373 priv->decided_udp_bitrate = TRUE;
375 _config_bitrate (factory);
379 gst_rtsp_media_factory_wfd_init (GstRTSPMediaFactoryWFD * factory)
381 GstRTSPMediaFactoryWFDPrivate *priv =
382 GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE (factory);
383 factory->priv = priv;
385 priv->launch = g_strdup (DEFAULT_LAUNCH);
386 priv->shared = DEFAULT_SHARED;
387 priv->protocols = DEFAULT_PROTOCOLS;
388 priv->buffer_size = DEFAULT_BUFFER_SIZE;
390 //priv->videosrc_type = GST_WFD_VSRC_XIMAGESRC;
391 //priv->videosrc_type = GST_WFD_VSRC_XVIMAGESRC;
392 //priv->videosrc_type = GST_WFD_VSRC_CAMERASRC;
393 priv->videosrc_type = GST_WFD_VSRC_VIDEOTESTSRC;
394 priv->video_codec = GST_WFD_VIDEO_H264;
395 priv->video_encoder = g_strdup ("omxh264enc");
396 priv->video_bitrate = 200000;
397 priv->video_width = 640;
398 priv->video_height = 480;
399 priv->video_framerate = 30;
400 priv->video_enc_skip_inbuf_value = 5;
401 priv->video_srcbin = NULL;
402 priv->min_udp_bitrate = 938861;
403 priv->max_udp_bitrate = 1572864;
404 priv->decided_udp_bitrate = FALSE;
406 priv->audio_device = g_strdup ("alsa_output.1.analog-stereo.monitor");
407 priv->audio_codec = GST_WFD_AUDIO_AAC;
408 priv->audio_encoder_aac = g_strdup ("avenc_aac");
409 priv->audio_encoder_ac3 = g_strdup ("avenc_ac3");
410 priv->audio_latency_time = 10000;
411 priv->audio_buffer_time = 200000;
412 priv->audio_do_timestamp = FALSE;
413 priv->audio_channels = GST_WFD_CHANNEL_2;
414 priv->audio_freq = GST_WFD_FREQ_48000;
415 priv->audio_srcbin = NULL;
417 g_mutex_init (&priv->direct_lock);
418 g_cond_init (&priv->direct_cond);
420 priv->discover_pipeline = NULL;
421 priv->direct_pipe = NULL;
422 memset (&priv->res, 0x00, sizeof (GstRTPSMediaWFDTypeFindResult));
423 priv->stream_bin = NULL;
425 priv->mux_queue = NULL;
428 g_mutex_init (&priv->lock);
432 gst_rtsp_media_factory_wfd_finalize (GObject * obj)
434 GstRTSPMediaFactoryWFD *factory = GST_RTSP_MEDIA_FACTORY_WFD (obj);
435 GstRTSPMediaFactoryWFDPrivate *priv = factory->priv;
437 if (priv->permissions)
438 gst_rtsp_permissions_unref (priv->permissions);
439 g_free (priv->launch);
440 g_mutex_clear (&priv->lock);
442 g_mutex_clear (&priv->direct_lock);
443 g_cond_clear (&priv->direct_cond);
445 if (priv->audio_device)
446 g_free (priv->audio_device);
447 if (priv->audio_encoder_aac)
448 g_free (priv->audio_encoder_aac);
449 if (priv->audio_encoder_ac3)
450 g_free (priv->audio_encoder_ac3);
452 if (priv->video_encoder)
453 g_free (priv->video_encoder);
455 G_OBJECT_CLASS (gst_rtsp_media_factory_wfd_parent_class)->finalize (obj);
458 GstRTSPMediaFactoryWFD *
459 gst_rtsp_media_factory_wfd_new (void)
461 GstRTSPMediaFactoryWFD *result;
463 result = g_object_new (GST_TYPE_RTSP_MEDIA_FACTORY_WFD, NULL);
469 gst_rtsp_media_factory_wfd_get_property (GObject * object,
470 guint propid, GValue * value, GParamSpec * pspec)
472 //GstRTSPMediaFactoryWFD *factory = GST_RTSP_MEDIA_FACTORY_WFD (object);
476 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
481 gst_rtsp_media_factory_wfd_set_property (GObject * object,
482 guint propid, const GValue * value, GParamSpec * pspec)
484 //GstRTSPMediaFactoryWFD *factory = GST_RTSP_MEDIA_FACTORY_WFD (object);
488 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
492 static GstPadProbeReturn
493 rtsp_media_wfd_dump_data (GstPad * pad, GstPadProbeInfo * info, gpointer u_data)
500 if (info->type == (GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_PUSH)) {
501 GstBuffer *buffer = gst_pad_probe_info_get_buffer (info);
503 gst_buffer_map (buffer, &mapinfo, GST_MAP_READ);
505 size = gst_buffer_get_size (buffer);
507 f = fopen ("/root/probe.ts", "a");
509 fwrite (data, size, 1, f);
512 gst_buffer_unmap (buffer, &mapinfo);
515 return GST_PAD_PROBE_OK;
519 _rtsp_media_factory_wfd_create_audio_capture_bin (GstRTSPMediaFactoryWFD *
520 factory, GstBin * srcbin)
522 GstElement *audiosrc = NULL;
523 GstElement *acaps = NULL;
524 GstElement *acaps2 = NULL;
525 GstElement *aenc = NULL;
526 GstElement *audio_convert = NULL;
527 GstElement *aqueue = NULL;
528 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
529 GstStructure *audio_properties_name = NULL;
532 gboolean is_enc_req = TRUE;
534 g_autofree gchar *acodec = NULL;
536 priv = factory->priv;
538 if (priv->audio_codec == GST_WFD_AUDIO_UNKNOWN) {
539 GST_INFO_OBJECT (factory, "Skip create audio source");
543 priv->audio_srcbin = (GstBin *)gst_bin_new ("audio");
545 /* create audio src element */
546 audiosrc = gst_element_factory_make ("pulsesrc", "audiosrc");
548 GST_ERROR_OBJECT (factory, "failed to create audiosrc element");
552 GST_INFO_OBJECT (factory, "audio device : %s", priv->audio_device);
553 GST_INFO_OBJECT (factory, "audio latency time : %"G_GUINT64_FORMAT,
554 priv->audio_latency_time);
555 GST_INFO_OBJECT (factory, "audio_buffer_time : %"G_GUINT64_FORMAT,
556 priv->audio_buffer_time);
557 GST_INFO_OBJECT (factory, "audio_do_timestamp : %d",
558 priv->audio_do_timestamp);
560 audio_properties_name = gst_structure_new_from_string (priv->audio_device);
562 g_object_set (audiosrc, "stream-properties", audio_properties_name, NULL);
563 g_object_set (audiosrc, "buffer-time", (gint64) priv->audio_buffer_time,
565 g_object_set (audiosrc, "latency-time", (gint64) priv->audio_latency_time,
567 g_object_set (audiosrc, "do-timestamp", (gboolean) priv->audio_do_timestamp,
569 g_object_set (audiosrc, "provide-clock", (gboolean) FALSE, NULL);
570 g_object_set (audiosrc, "is-live", (gboolean) TRUE, NULL);
572 if (priv->audio_codec == GST_WFD_AUDIO_LPCM) {
573 /* To meet miracast certification */
574 gint64 block_size = 1920;
575 g_object_set (audiosrc, "blocksize", (gint64) block_size, NULL);
577 audio_convert = gst_element_factory_make ("capssetter", "audio_convert");
578 if (NULL == audio_convert) {
579 GST_ERROR_OBJECT (factory, "failed to create audio convert element");
582 g_object_set (audio_convert, "caps", gst_caps_new_simple ("audio/x-lpcm",
583 "width", G_TYPE_INT, 16,
584 "rate", G_TYPE_INT, 48000,
585 "channels", G_TYPE_INT, 2,
586 "dynamic_range", G_TYPE_INT, 0,
587 "emphasis", G_TYPE_BOOLEAN, FALSE,
588 "mute", G_TYPE_BOOLEAN, FALSE, NULL), NULL);
589 g_object_set (audio_convert, "join", (gboolean) FALSE, NULL);
590 g_object_set (audio_convert, "replace", (gboolean) TRUE, NULL);
592 acaps2 = gst_element_factory_make ("capsfilter", "audiocaps2");
593 if (NULL == acaps2) {
594 GST_ERROR_OBJECT (factory, "failed to create audio capsilfter element");
597 /* In case of LPCM, uses big endian */
598 g_object_set (G_OBJECT (acaps2), "caps",
599 gst_caps_new_simple ("audio/x-raw", "format", G_TYPE_STRING, "S16BE",
600 /* In case of LPCM, uses big endian */
601 "rate", G_TYPE_INT, 48000,
602 "channels", G_TYPE_INT, 2, NULL), NULL);
605 /* create audio caps element */
606 acaps = gst_element_factory_make ("capsfilter", "audiocaps");
608 GST_ERROR_OBJECT (factory, "failed to create audio capsilfter element");
612 if (priv->audio_channels == GST_WFD_CHANNEL_2)
614 else if (priv->audio_channels == GST_WFD_CHANNEL_4)
616 else if (priv->audio_channels == GST_WFD_CHANNEL_6)
618 else if (priv->audio_channels == GST_WFD_CHANNEL_8)
623 if (priv->audio_freq == GST_WFD_FREQ_44100)
625 else if (priv->audio_freq == GST_WFD_FREQ_48000)
630 if (priv->audio_codec == GST_WFD_AUDIO_LPCM) {
631 g_object_set (G_OBJECT (acaps), "caps",
632 gst_caps_new_simple ("audio/x-lpcm", "width", G_TYPE_INT, 16,
633 "rate", G_TYPE_INT, 48000,
634 "channels", G_TYPE_INT, 2,
635 "dynamic_range", G_TYPE_INT, 0,
636 "emphasis", G_TYPE_BOOLEAN, FALSE,
637 "mute", G_TYPE_BOOLEAN, FALSE, NULL), NULL);
638 } else if ((priv->audio_codec == GST_WFD_AUDIO_AAC)
639 || (priv->audio_codec == GST_WFD_AUDIO_AC3)) {
640 g_object_set (G_OBJECT (acaps), "caps", gst_caps_new_simple ("audio/x-raw",
641 "endianness", G_TYPE_INT, 1234, "signed", G_TYPE_BOOLEAN, TRUE,
642 "depth", G_TYPE_INT, 16, "rate", G_TYPE_INT, freq, "channels",
643 G_TYPE_INT, channels, NULL), NULL);
646 if (priv->audio_codec == GST_WFD_AUDIO_AAC) {
647 acodec = g_strdup (priv->audio_encoder_aac);
649 } else if (priv->audio_codec == GST_WFD_AUDIO_AC3) {
650 acodec = g_strdup (priv->audio_encoder_ac3);
652 } else if (priv->audio_codec == GST_WFD_AUDIO_LPCM) {
653 GST_DEBUG_OBJECT (factory, "No codec required, raw data will be sent");
656 GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
661 aenc = gst_element_factory_make (acodec, "audioenc");
663 GST_ERROR_OBJECT (factory, "failed to create audio encoder element");
667 g_object_set (aenc, "compliance", -2, NULL);
668 g_object_set (aenc, "tolerance", 400000000, NULL);
669 g_object_set (aenc, "bitrate", (guint) 128000, NULL);
670 g_object_set (aenc, "rate-control", 2, NULL);
672 aqueue = gst_element_factory_make ("queue", "audio-queue");
674 GST_ERROR_OBJECT (factory, "failed to create audio queue element");
678 gst_bin_add_many (priv->audio_srcbin, audiosrc, acaps, aenc, aqueue, NULL);
679 gst_bin_add (srcbin, GST_ELEMENT (priv->audio_srcbin));
681 if (!gst_element_link_many (audiosrc, acaps, aenc, aqueue, NULL)) {
682 GST_ERROR_OBJECT (factory, "Failed to link audio src elements...");
686 aqueue = gst_element_factory_make ("queue", "audio-queue");
688 GST_ERROR_OBJECT (factory, "failed to create audio queue element");
692 gst_bin_add_many (priv->audio_srcbin, audiosrc, acaps2, audio_convert, acaps, aqueue, NULL);
693 gst_bin_add (srcbin, GST_ELEMENT (priv->audio_srcbin));
695 if (!gst_element_link_many (audiosrc, acaps2, audio_convert, acaps, aqueue,
697 GST_ERROR_OBJECT (factory, "Failed to link audio src elements...");
702 priv->audio_queue = aqueue;
703 if (audio_properties_name)
704 gst_structure_free (audio_properties_name);
708 gst_object_unref (acaps);
709 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 GstElement *venc = NULL;
724 GstElement *vparse = NULL;
725 GstElement *vqueue = NULL;
726 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
728 priv = factory->priv;
730 GST_INFO_OBJECT (factory, "picked videotestsrc as video source");
731 priv->video_srcbin = (GstBin *)gst_bin_new ("video");
733 videosrc = gst_element_factory_make ("videotestsrc", "videosrc");
734 if (NULL == videosrc) {
735 GST_ERROR_OBJECT (factory, "failed to create ximagesrc element");
739 /* create video caps element */
740 vcaps = gst_element_factory_make ("capsfilter", "videocaps");
742 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
746 g_object_set (G_OBJECT (vcaps), "caps",
747 gst_caps_new_simple ("video/x-raw",
748 "format", G_TYPE_STRING, "I420",
749 "width", G_TYPE_INT, priv->video_width,
750 "height", G_TYPE_INT, priv->video_height,
751 "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
754 /* create video convert element */
755 videoconvert = gst_element_factory_make ("videoconvert", "videoconvert");
756 if (NULL == videoconvert) {
757 GST_ERROR_OBJECT (factory, "failed to create video videoconvert element");
761 venc_caps = gst_element_factory_make ("capsfilter", "venc_caps");
762 if (NULL == venc_caps) {
763 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
767 g_object_set (G_OBJECT (venc_caps), "caps",
768 gst_caps_new_simple ("video/x-raw",
769 "format", G_TYPE_STRING, "SN12",
770 "width", G_TYPE_INT, priv->video_width,
771 "height", G_TYPE_INT, priv->video_height,
772 "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
775 if (priv->video_codec != GST_WFD_VIDEO_H264) {
776 GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
780 venc = gst_element_factory_make (priv->video_encoder, "videoenc");
782 GST_ERROR_OBJECT (factory, "failed to create video encoder element");
786 g_object_set (venc, "aud", 0, NULL);
787 g_object_set (venc, "byte-stream", 1, NULL);
788 g_object_set (venc, "bitrate", 512, NULL);
790 vparse = gst_element_factory_make ("h264parse", "videoparse");
791 if (NULL == vparse) {
792 GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
795 g_object_set (vparse, "config-interval", 1, NULL);
797 vqueue = gst_element_factory_make ("queue", "video-queue");
799 GST_ERROR_OBJECT (factory, "failed to create video queue element");
803 gst_bin_add_many (priv->video_srcbin, videosrc, vcaps, videoconvert, venc_caps, venc, vparse, vqueue, NULL);
804 gst_bin_add (srcbin, GST_ELEMENT (priv->video_srcbin));
805 if (!gst_element_link_many (videosrc, vcaps, videoconvert, venc_caps, venc,
806 vparse, vqueue, NULL)) {
807 GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
811 priv->video_queue = vqueue;
817 gst_object_unref(videosrc);
818 gst_object_unref(vcaps);
819 gst_object_unref(videoconvert);
820 gst_object_unref(venc_caps);
821 gst_object_unref(venc);
822 gst_object_unref(vparse);
823 gst_object_unref(vqueue);
828 _rtsp_media_factory_wfd_create_waylandsrc_bin (GstRTSPMediaFactoryWFD * factory,
831 GstElement *videosrc = NULL;
832 GstElement *vcaps = NULL;
833 GstElement *venc = NULL;
834 GstElement *vparse = NULL;
835 GstElement *vqueue = NULL;
836 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
838 priv = factory->priv;
840 GST_INFO_OBJECT (factory, "picked waylandsrc as video source");
842 if (priv->video_codec == GST_WFD_VIDEO_UNKNOWN) {
843 GST_INFO_OBJECT (factory, "Skip create video source.");
847 priv->video_srcbin = (GstBin *)gst_bin_new ("video");
849 videosrc = gst_element_factory_make ("waylandsrc", "videosrc");
850 if (NULL == videosrc) {
851 GST_ERROR_OBJECT (factory, "failed to create ximagesrc element");
855 /* create video caps element */
856 vcaps = gst_element_factory_make ("capsfilter", "videocaps");
858 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
862 g_object_set (G_OBJECT (vcaps), "caps",
863 gst_caps_new_simple ("video/x-raw",
864 "format", G_TYPE_STRING, "SN12",
865 "width", G_TYPE_INT, priv->video_width,
866 "height", G_TYPE_INT, priv->video_height,
867 "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
870 if (priv->video_codec != GST_WFD_VIDEO_H264) {
871 GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
875 venc = gst_element_factory_make (priv->video_encoder, "videoenc");
877 GST_ERROR_OBJECT (factory, "failed to create video encoder element");
881 g_object_set (venc, "aud", 0, NULL);
882 g_object_set (venc, "byte-stream", 1, NULL);
883 g_object_set (venc, "bitrate", 512, NULL);
884 g_object_set (venc, "target-bitrate", priv->video_bitrate, NULL);
886 vparse = gst_element_factory_make ("h264parse", "videoparse");
887 if (NULL == vparse) {
888 GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
891 g_object_set (vparse, "config-interval", 1, NULL);
893 vqueue = gst_element_factory_make ("queue", "video-queue");
895 GST_ERROR_OBJECT (factory, "failed to create video queue element");
899 gst_bin_add_many (priv->video_srcbin, videosrc, vcaps, venc, vparse, vqueue, NULL);
900 gst_bin_add (srcbin, GST_ELEMENT (priv->video_srcbin));
901 if (!gst_element_link_many (videosrc, vcaps, venc, vparse, vqueue, NULL)) {
902 GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
906 priv->video_queue = vqueue;
912 gst_object_unref (videosrc);
913 gst_object_unref (vqueue);
918 _rtsp_media_factory_wfd_create_camera_capture_bin (GstRTSPMediaFactoryWFD *
919 factory, GstBin * srcbin)
921 GstElement *videosrc = NULL;
922 GstElement *vcaps = NULL;
923 GstElement *venc = NULL;
924 GstElement *vparse = NULL;
925 GstElement *vqueue = NULL;
926 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
928 priv = factory->priv;
929 priv->video_srcbin = (GstBin *)gst_bin_new ("video");
931 videosrc = gst_element_factory_make ("camerasrc", "videosrc");
932 if (NULL == videosrc) {
933 GST_ERROR_OBJECT (factory, "failed to create camerasrc element");
937 /* create video caps element */
938 vcaps = gst_element_factory_make ("capsfilter", "videocaps");
940 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
944 GST_INFO_OBJECT (factory, "picked camerasrc as video source");
945 g_object_set (G_OBJECT (vcaps), "caps",
946 gst_caps_new_simple ("video/x-raw",
947 "width", G_TYPE_INT, priv->video_width,
948 "height", G_TYPE_INT, priv->video_height,
949 "format", G_TYPE_STRING, "SN12",
950 "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
953 if (priv->video_codec != GST_WFD_VIDEO_H264) {
954 GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
958 venc = gst_element_factory_make (priv->video_encoder, "videoenc");
960 GST_ERROR_OBJECT (factory, "failed to create video encoder element");
964 g_object_set (venc, "bitrate", priv->video_bitrate, NULL);
965 g_object_set (venc, "byte-stream", 1, NULL);
966 g_object_set (venc, "append-dci", 1, NULL);
968 vparse = gst_element_factory_make ("h264parse", "videoparse");
969 if (NULL == vparse) {
970 GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
973 g_object_set (vparse, "config-interval", 1, NULL);
975 vqueue = gst_element_factory_make ("queue", "video-queue");
977 GST_ERROR_OBJECT (factory, "failed to create video queue element");
981 gst_bin_add_many (priv->video_srcbin, videosrc, vcaps, venc, vparse, vqueue, NULL);
982 gst_bin_add (srcbin, GST_ELEMENT (priv->video_srcbin));
984 if (!gst_element_link_many (videosrc, vcaps, venc, vparse, vqueue, NULL)) {
985 GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
989 priv->video_queue = vqueue;
995 gst_object_unref (videosrc);
996 gst_object_unref (vqueue);
1001 _rtsp_media_factory_wfd_create_xcapture_bin (GstRTSPMediaFactoryWFD * factory,
1004 GstElement *videosrc = NULL;
1005 GstElement *vcaps = NULL;
1006 GstElement *venc_caps = NULL;
1007 GstElement *videoconvert = NULL, *videoscale = NULL;
1008 GstElement *venc = NULL;
1009 GstElement *vparse = NULL;
1010 GstElement *vqueue = NULL;
1011 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1013 priv = factory->priv;
1015 GST_INFO_OBJECT (factory, "picked ximagesrc as video source");
1016 priv->video_srcbin = (GstBin *)gst_bin_new ("video");
1018 videosrc = gst_element_factory_make ("ximagesrc", "videosrc");
1019 if (NULL == videosrc) {
1020 GST_ERROR_OBJECT (factory, "failed to create ximagesrc element");
1024 videoscale = gst_element_factory_make ("videoscale", "videoscale");
1025 if (NULL == videoscale) {
1026 GST_ERROR_OBJECT (factory, "failed to create videoscale element");
1030 videoconvert = gst_element_factory_make ("videoconvert", "videoconvert");
1031 if (NULL == videoconvert) {
1032 GST_ERROR_OBJECT (factory, "failed to create videoconvert element");
1036 /* create video caps element */
1037 vcaps = gst_element_factory_make ("capsfilter", "videocaps");
1038 if (NULL == vcaps) {
1039 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
1043 g_object_set (G_OBJECT (vcaps), "caps",
1044 gst_caps_new_simple ("video/x-raw",
1045 "width", G_TYPE_INT, priv->video_width,
1046 "height", G_TYPE_INT, priv->video_height,
1047 "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
1050 if (priv->video_codec != GST_WFD_VIDEO_H264) {
1051 GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
1055 venc = gst_element_factory_make (priv->video_encoder, "videoenc");
1057 GST_ERROR_OBJECT (factory, "failed to create video encoder element");
1061 g_object_set (venc, "aud", 0, NULL);
1062 g_object_set (venc, "byte-stream", 1, NULL);
1063 g_object_set (venc, "bitrate", 512, NULL);
1065 venc_caps = gst_element_factory_make ("capsfilter", "venc_caps");
1066 if (NULL == venc_caps) {
1067 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
1071 g_object_set (G_OBJECT (venc_caps), "caps",
1072 gst_caps_new_simple ("video/x-h264",
1073 "profile", G_TYPE_STRING, "baseline", NULL), NULL);
1075 vparse = gst_element_factory_make ("h264parse", "videoparse");
1076 if (NULL == vparse) {
1077 GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
1080 g_object_set (vparse, "config-interval", 1, NULL);
1082 vqueue = gst_element_factory_make ("queue", "video-queue");
1084 GST_ERROR_OBJECT (factory, "failed to create video queue element");
1088 gst_bin_add_many (priv->video_srcbin, videosrc, videoscale, videoconvert, vcaps, venc,
1089 venc_caps, vparse, vqueue, NULL);
1090 gst_bin_add (srcbin, GST_ELEMENT (priv->video_srcbin));
1091 if (!gst_element_link_many (videosrc, videoscale, videoconvert, vcaps, venc,
1092 venc_caps, vparse, vqueue, NULL)) {
1093 GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
1097 priv->video_queue = vqueue;
1103 gst_object_unref(videosrc);
1104 gst_object_unref(vcaps);
1105 gst_object_unref(venc_caps);
1106 gst_object_unref(videoconvert);
1107 gst_object_unref(videoscale);
1108 gst_object_unref(venc);
1109 gst_object_unref(vparse);
1110 gst_object_unref(vqueue);
1115 _rtsp_media_factory_wfd_create_xvcapture_bin (GstRTSPMediaFactoryWFD * factory,
1118 GstElement *videosrc = NULL;
1119 GstElement *vcaps = NULL;
1120 GstElement *venc = NULL;
1121 GstElement *vparse = NULL;
1122 GstElement *vqueue = NULL;
1123 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1125 priv = factory->priv;
1127 GST_INFO_OBJECT (factory, "picked xvimagesrc as video source");
1128 priv->video_srcbin = (GstBin *)gst_bin_new ("video");
1130 videosrc = gst_element_factory_make ("xvimagesrc", "videosrc");
1131 if (NULL == videosrc) {
1132 GST_ERROR_OBJECT (factory, "failed to create xvimagesrc element");
1136 /* create video caps element */
1137 vcaps = gst_element_factory_make ("capsfilter", "videocaps");
1138 if (NULL == vcaps) {
1139 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
1143 g_object_set (G_OBJECT (vcaps), "caps",
1144 gst_caps_new_simple ("video/x-raw",
1145 "width", G_TYPE_INT, priv->video_width,
1146 "height", G_TYPE_INT, priv->video_height,
1147 "format", G_TYPE_STRING, "SN12",
1148 "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
1151 if (priv->video_codec != GST_WFD_VIDEO_H264) {
1152 GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
1156 venc = gst_element_factory_make (priv->video_encoder, "videoenc");
1158 GST_ERROR_OBJECT (factory, "failed to create video encoder element");
1161 g_object_set (venc, "bitrate", priv->video_bitrate, NULL);
1162 g_object_set (venc, "byte-stream", 1, NULL);
1163 g_object_set (venc, "append-dci", 1, NULL);
1164 g_object_set (venc, "idr-period", 120, NULL);
1165 g_object_set (venc, "skip-inbuf", priv->video_enc_skip_inbuf_value, NULL);
1167 vparse = gst_element_factory_make ("h264parse", "videoparse");
1168 if (NULL == vparse) {
1169 GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
1172 g_object_set (vparse, "config-interval", 1, NULL);
1174 vqueue = gst_element_factory_make ("queue", "video-queue");
1176 GST_ERROR_OBJECT (factory, "failed to create video queue element");
1180 gst_bin_add_many (priv->video_srcbin, videosrc, vcaps, venc, vparse, vqueue, NULL);
1181 gst_bin_add (srcbin, GST_ELEMENT (priv->video_srcbin));
1182 if (!gst_element_link_many (videosrc, vcaps, venc, vparse, vqueue, NULL)) {
1183 GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
1187 priv->video_queue = vqueue;
1193 gst_object_unref (videosrc);
1194 gst_object_unref (vqueue);
1200 _rtsp_media_factory_wfd_create_srcbin (GstRTSPMediaFactoryWFD * factory)
1202 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1204 GstBin *srcbin = NULL;
1205 GstElement *mux = NULL;
1206 GstElement *mux_queue = NULL;
1207 GstElement *payload = NULL;
1208 GstPad *srcpad = NULL;
1209 GstPad *mux_vsinkpad = NULL;
1210 GstPad *mux_asinkpad = NULL;
1211 GstPad *ghost_pad = NULL;
1213 priv = factory->priv;
1215 /* create source bin */
1216 srcbin = GST_BIN (gst_bin_new ("srcbin"));
1218 GST_ERROR_OBJECT (factory, "failed to create source bin...");
1222 GST_INFO_OBJECT (factory, "Check video codec... %d", priv->video_codec);
1223 /* create video src element */
1224 switch (priv->videosrc_type) {
1225 case GST_WFD_VSRC_XIMAGESRC:
1226 if (!_rtsp_media_factory_wfd_create_xcapture_bin (factory, srcbin)) {
1227 GST_ERROR_OBJECT (factory, "failed to create xcapture bin...");
1231 case GST_WFD_VSRC_XVIMAGESRC:
1232 if (!_rtsp_media_factory_wfd_create_xvcapture_bin (factory, srcbin)) {
1233 GST_ERROR_OBJECT (factory, "failed to create xvcapture bin...");
1237 case GST_WFD_VSRC_CAMERASRC:
1238 if (!_rtsp_media_factory_wfd_create_camera_capture_bin (factory, srcbin)) {
1239 GST_ERROR_OBJECT (factory, "failed to create camera capture bin...");
1243 case GST_WFD_VSRC_VIDEOTESTSRC:
1244 if (!_rtsp_media_factory_wfd_create_videotest_bin (factory, srcbin)) {
1245 GST_ERROR_OBJECT (factory, "failed to create videotestsrc bin...");
1249 case GST_WFD_VSRC_WAYLANDSRC:
1250 if (!_rtsp_media_factory_wfd_create_waylandsrc_bin (factory, srcbin)) {
1251 GST_ERROR_OBJECT (factory, "failed to create videotestsrc bin...");
1256 GST_ERROR_OBJECT (factory, "unknow mode selected...");
1260 mux = gst_element_factory_make ("mpegtsmux", "tsmux");
1262 GST_ERROR_OBJECT (factory, "failed to create muxer element");
1266 g_object_set (mux, "wfd-mode", TRUE, NULL);
1268 mux_queue = gst_element_factory_make ("queue", "muxer-queue");
1270 GST_ERROR_OBJECT (factory, "failed to create muxer-queue element");
1274 g_object_set (mux_queue, "max-size-buffers", 20000, NULL);
1276 payload = gst_element_factory_make ("rtpmp2tpay", "pay0");
1278 GST_ERROR_OBJECT (factory, "failed to create payload element");
1282 g_object_set (payload, "pt", 33, NULL);
1283 g_object_set (payload, "mtu", priv->mtu_size, NULL);
1284 g_object_set (payload, "rtp-flush", (gboolean) TRUE, NULL);
1286 gst_bin_add_many (srcbin, mux, mux_queue, payload, NULL);
1288 if (!gst_element_link_many (mux, mux_queue, payload, NULL)) {
1289 GST_ERROR_OBJECT (factory, "Failed to link muxer & payload...");
1293 if (priv->video_codec > GST_WFD_VIDEO_UNKNOWN) {
1294 /* request video sink pad from muxer, which has elementary pid 0x1011 */
1295 mux_vsinkpad = gst_element_get_request_pad (mux, "sink_4113");
1296 if (!mux_vsinkpad) {
1297 GST_ERROR_OBJECT (factory, "Failed to get sink pad from muxer...");
1301 /* request srcpad from video queue */
1302 srcpad = gst_element_get_static_pad (priv->video_queue, "src");
1304 GST_ERROR_OBJECT (factory, "Failed to get srcpad from video queue...");
1307 ghost_pad = gst_ghost_pad_new ("video_src", srcpad);
1308 gst_element_add_pad (GST_ELEMENT (priv->video_srcbin), ghost_pad);
1310 if (gst_pad_link (ghost_pad, mux_vsinkpad) != GST_PAD_LINK_OK) {
1311 GST_ERROR_OBJECT (factory,
1312 "Failed to link video queue src pad & muxer video sink pad...");
1316 gst_object_unref (mux_vsinkpad);
1317 gst_object_unref (srcpad);
1322 GST_INFO_OBJECT (factory, "Check audio codec... %d", priv->audio_codec);
1324 /* create audio source elements & add to pipeline */
1325 if (!_rtsp_media_factory_wfd_create_audio_capture_bin (factory, srcbin))
1328 if (priv->audio_codec > GST_WFD_AUDIO_UNKNOWN) {
1329 /* request audio sink pad from muxer, which has elementary pid 0x1100 */
1330 mux_asinkpad = gst_element_get_request_pad (mux, "sink_4352");
1331 if (!mux_asinkpad) {
1332 GST_ERROR_OBJECT (factory, "Failed to get sinkpad from muxer...");
1336 /* request srcpad from audio queue */
1337 srcpad = gst_element_get_static_pad (priv->audio_queue, "src");
1339 GST_ERROR_OBJECT (factory, "Failed to get srcpad from audio queue...");
1342 ghost_pad = gst_ghost_pad_new ("audio_src", srcpad);
1343 gst_element_add_pad (GST_ELEMENT (priv->audio_srcbin), ghost_pad);
1345 /* link audio queue's srcpad & muxer sink pad */
1346 if (gst_pad_link (ghost_pad, mux_asinkpad) != GST_PAD_LINK_OK) {
1347 GST_ERROR_OBJECT (factory,
1348 "Failed to link audio queue src pad & muxer audio sink pad...");
1351 gst_object_unref (mux_asinkpad);
1352 gst_object_unref (srcpad);
1357 GstPad *pad_probe = NULL;
1358 pad_probe = gst_element_get_static_pad (mux, "src");
1360 if (NULL == pad_probe) {
1361 GST_INFO_OBJECT (factory, "pad for probe not created");
1363 GST_INFO_OBJECT (factory, "pad for probe SUCCESSFUL");
1365 gst_pad_add_probe (pad_probe, GST_PAD_PROBE_TYPE_BUFFER,
1366 rtsp_media_wfd_dump_data, factory, NULL);
1368 gst_object_unref (pad_probe);
1371 GST_DEBUG_OBJECT (factory, "successfully created source bin...");
1373 priv->stream_bin = srcbin;
1374 priv->mux = gst_object_ref (mux);
1375 priv->mux_queue = gst_object_ref (mux_queue);
1376 priv->pay = gst_object_ref (payload);
1378 return GST_ELEMENT_CAST (srcbin);
1381 GST_ERROR_OBJECT (factory, "Failed to create pipeline");
1383 gst_object_unref (mux_vsinkpad);
1385 gst_object_unref (mux_asinkpad);
1387 gst_object_unref (srcpad);
1389 gst_object_unref (srcbin);
1394 rtsp_media_factory_wfd_create_element (GstRTSPMediaFactory * factory,
1395 const GstRTSPUrl * url)
1397 GstRTSPMediaFactoryWFD *_factory = GST_RTSP_MEDIA_FACTORY_WFD_CAST (factory);
1398 GstElement *element = NULL;
1400 GST_RTSP_MEDIA_FACTORY_WFD_LOCK (factory);
1402 element = _rtsp_media_factory_wfd_create_srcbin (_factory);
1404 GST_RTSP_MEDIA_FACTORY_WFD_UNLOCK (factory);
1409 static GstRTSPMedia *
1410 rtsp_media_factory_wfd_construct (GstRTSPMediaFactory * factory,
1411 const GstRTSPUrl * url)
1413 GstRTSPMedia *media;
1414 GstElement *element, *pipeline;
1415 GstRTSPMediaFactoryClass *klass;
1417 klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
1419 if (!klass->create_pipeline)
1422 element = gst_rtsp_media_factory_create_element (factory, url);
1423 if (element == NULL)
1426 /* create a new empty media */
1427 media = gst_rtsp_media_new (element);
1428 //media = g_object_new (GST_TYPE_RTSP_MEDIA_EXT, "element", element, NULL);
1430 gst_rtsp_media_collect_streams (media);
1432 pipeline = klass->create_pipeline (factory, media);
1433 if (pipeline == NULL)
1441 g_critical ("no create_pipeline function");
1446 g_critical ("could not create element");
1451 g_critical ("can't create pipeline");
1452 g_object_unref (media);
1457 gint type_detected = FALSE;
1458 gint linked = FALSE;
1459 static gint in_pad_probe;
1461 static GstPadProbeReturn
1462 _rtsp_media_factory_wfd_restore_pipe_probe_cb (GstPad *pad, GstPadProbeInfo *info, gpointer user_data)
1464 GstPad *old_src = NULL;
1465 GstPad *sink = NULL;
1466 GstPad *old_sink = NULL;
1467 GstPad *new_src = NULL;
1468 GstRTSPMediaFactoryWFD *factory = NULL;
1469 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1470 GstRTSPMediaWFDDirectPipelineData *pipe_data = NULL;
1472 if (!g_atomic_int_compare_and_exchange (&in_pad_probe, FALSE, TRUE))
1473 return GST_PAD_PROBE_OK;
1475 factory = (GstRTSPMediaFactoryWFD *) user_data;
1476 priv = factory->priv;
1477 pipe_data = priv->direct_pipe;
1479 gst_element_sync_state_with_parent (GST_ELEMENT(priv->audio_srcbin));
1480 gst_element_sync_state_with_parent (GST_ELEMENT(priv->video_srcbin));
1481 gst_element_sync_state_with_parent (GST_ELEMENT(priv->mux));
1482 gst_element_sync_state_with_parent (GST_ELEMENT(priv->mux_queue));
1484 sink = gst_element_get_static_pad (priv->pay, "sink");
1485 old_src = gst_pad_get_peer (sink);
1486 gst_pad_unlink (old_src, sink);
1488 new_src = gst_element_get_static_pad (priv->mux_queue, "src");
1489 old_sink = gst_pad_get_peer (new_src);
1490 gst_pad_unlink (new_src, old_sink);
1491 gst_element_set_state (priv->stub_fs, GST_STATE_NULL);
1492 gst_bin_remove ((GstBin *)priv->stream_bin, priv->stub_fs);
1494 gst_pad_link (new_src, sink);
1495 gst_object_unref (new_src);
1496 gst_object_unref (old_sink);
1498 gst_element_set_state (GST_ELEMENT(pipe_data->pipeline), GST_STATE_PAUSED);
1500 /* signal that new pipeline linked */
1501 g_mutex_lock (&priv->direct_lock);
1502 g_cond_signal (&priv->direct_cond);
1504 g_mutex_unlock (&priv->direct_lock);
1506 return GST_PAD_PROBE_REMOVE;
1510 _rtsp_media_factory_wfd_destroy_direct_pipe(void *user_data)
1512 GstRTSPMediaFactoryWFD *factory = NULL;
1513 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1514 GstRTSPMediaWFDDirectPipelineData *pipe_data = NULL;
1516 factory = (GstRTSPMediaFactoryWFD *) user_data;
1517 priv = factory->priv;
1518 pipe_data = priv->direct_pipe;
1520 GST_DEBUG_OBJECT (factory, "Deleting pipeline");
1521 gst_element_set_state (GST_ELEMENT(pipe_data->pipeline), GST_STATE_NULL);
1522 gst_bin_remove ((GstBin *)priv->stream_bin, GST_ELEMENT(pipe_data->pipeline));
1524 g_signal_emit (factory,
1525 gst_rtsp_media_factory_wfd_signals[SIGNAL_DIRECT_STREAMING_END], 0, NULL);
1530 _rtsp_media_factory_wfd_demux_pad_added_cb (GstElement *element,
1534 GstPad *sinkpad = NULL;
1535 GstRTSPMediaFactoryWFD *factory = NULL;
1536 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1537 GstRTSPMediaWFDDirectPipelineData *pipe_data = NULL;
1539 GstCaps *caps = gst_pad_get_current_caps (pad);
1540 g_autofree gchar *pad_name = gst_pad_get_name (pad);
1541 g_autofree gchar *caps_string = gst_caps_to_string (caps);
1542 g_autofree gchar *temp_caps = NULL;
1544 gst_caps_unref (caps);
1546 factory = (GstRTSPMediaFactoryWFD *) data;
1547 priv = factory->priv;
1548 pipe_data = priv->direct_pipe;
1549 temp_caps = g_ascii_strdown(caps_string, -1);
1551 if (g_strrstr (temp_caps, "audio")) {
1552 sinkpad = gst_element_get_static_pad (pipe_data->ap, "sink");
1553 if (gst_pad_is_linked (sinkpad)) {
1554 gst_object_unref (sinkpad);
1555 GST_DEBUG_OBJECT (factory, "pad linked");
1558 if (gst_pad_link (pad, sinkpad) != GST_PAD_LINK_OK)
1559 GST_DEBUG_OBJECT (factory, "can't link demux %s pad", pad_name);
1561 gst_object_unref (sinkpad);
1565 if (g_strrstr (temp_caps, "video")) {
1566 if (g_strrstr (temp_caps, "h264")) {
1567 sinkpad = gst_element_get_static_pad (pipe_data->vp, "sink");
1568 if (gst_pad_link (pad, sinkpad) != GST_PAD_LINK_OK)
1569 GST_DEBUG_OBJECT (factory, "can't link demux %s pad", pad_name);
1571 gst_object_unref (sinkpad);
1577 static GstPadProbeReturn
1578 _rtsp_media_factory_wfd_pay_pad_probe_cb (GstPad *pad, GstPadProbeInfo *info, gpointer user_data)
1580 GstPad *old_src = NULL;
1581 GstPad *sink = NULL;
1582 GstPad *old_sink = NULL;
1583 GstPad *new_src = NULL;
1584 GstPad *fas_sink = NULL;
1586 GstRTSPMediaFactoryWFD *factory = NULL;
1587 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1588 GstRTSPMediaWFDDirectPipelineData *pipe_data = NULL;
1590 if (!g_atomic_int_compare_and_exchange (&in_pad_probe, FALSE, TRUE))
1591 return GST_PAD_PROBE_OK;
1593 factory = (GstRTSPMediaFactoryWFD *) user_data;
1594 priv = factory->priv;
1595 pipe_data = priv->direct_pipe;
1597 sink = gst_element_get_static_pad (priv->pay, "sink");
1598 old_src = gst_pad_get_peer (sink);
1599 gst_pad_unlink (old_src, sink);
1601 new_src = gst_element_get_static_pad (pipe_data->tsmux, "src");
1602 old_sink = gst_pad_get_peer (new_src);
1603 gst_pad_unlink (new_src, old_sink);
1604 gst_element_set_state (pipe_data->mux_fs, GST_STATE_NULL);
1605 gst_bin_remove ((GstBin *)pipe_data->pipeline, pipe_data->mux_fs);
1607 gp = gst_ghost_pad_new ("audio_file", new_src);
1608 gst_pad_set_active(gp,TRUE);
1609 gst_element_add_pad (GST_ELEMENT (pipe_data->pipeline), gp);
1610 gst_pad_link (gp, sink);
1611 gst_object_unref (new_src);
1612 gst_object_unref (old_sink);
1614 priv->stub_fs = gst_element_factory_make ("fakesink", NULL);
1615 gst_bin_add (priv->stream_bin, priv->stub_fs);
1616 gst_element_sync_state_with_parent (priv->stub_fs);
1617 fas_sink = gst_element_get_static_pad (priv->stub_fs, "sink");
1618 gst_pad_link (old_src, fas_sink);
1619 gst_object_unref (old_src);
1620 gst_object_unref (fas_sink);
1621 gst_element_set_state (GST_ELEMENT(priv->audio_srcbin), GST_STATE_PAUSED);
1622 gst_element_set_state (GST_ELEMENT(priv->video_srcbin), GST_STATE_PAUSED);
1623 gst_element_set_state (GST_ELEMENT(priv->mux), GST_STATE_PAUSED);
1624 gst_element_set_state (GST_ELEMENT(priv->mux_queue), GST_STATE_PAUSED);
1626 /* signal that new pipeline linked */
1627 g_mutex_lock (&priv->direct_lock);
1629 g_cond_signal (&priv->direct_cond);
1630 g_mutex_unlock (&priv->direct_lock);
1632 return GST_PAD_PROBE_REMOVE;
1636 _rtsp_media_factory_wfd_relink_pipeline(GstRTSPMediaFactoryWFD * factory)
1638 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1639 GstPad *probe_pad = NULL;
1640 gint64 end_time = 0;
1642 priv = factory->priv;
1644 probe_pad = gst_element_get_static_pad (priv->pay, "sink");
1645 if (probe_pad == NULL)
1648 in_pad_probe = FALSE;
1650 gst_pad_add_probe (probe_pad, GST_PAD_PROBE_TYPE_IDLE, _rtsp_media_factory_wfd_restore_pipe_probe_cb, factory, NULL);
1652 g_mutex_lock (&factory->priv->direct_lock);
1653 end_time = g_get_monotonic_time () + 5 * G_TIME_SPAN_SECOND;
1654 if (!g_cond_wait_until (&factory->priv->direct_cond, &factory->priv->direct_lock, end_time)) {
1655 g_mutex_unlock (&factory->priv->direct_lock);
1656 GST_ERROR_OBJECT (factory, "Failed to relink pipeline");
1659 g_mutex_unlock (&factory->priv->direct_lock);
1664 static GstPadProbeReturn
1665 _rtsp_media_factory_wfd_src_pad_probe_cb(GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1667 GstRTSPMediaFactoryWFD *factory = NULL;
1668 GstEvent *event = GST_PAD_PROBE_INFO_EVENT(info);
1670 factory = (GstRTSPMediaFactoryWFD *) user_data;
1672 if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
1673 GST_INFO_OBJECT (factory, "Got event: %s in direct streaming", GST_EVENT_TYPE_NAME (event));
1675 info->data = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, gst_structure_new_empty ("fillEOS"));
1677 if (!_rtsp_media_factory_wfd_relink_pipeline(factory)) {
1678 GST_ERROR_OBJECT (factory, "Failed to relink pipeline");
1679 return GST_PAD_PROBE_REMOVE;
1682 g_idle_add((GSourceFunc)_rtsp_media_factory_wfd_destroy_direct_pipe, factory);
1683 return GST_PAD_PROBE_REMOVE;
1686 return GST_PAD_PROBE_OK;
1690 _rtsp_media_factory_wfd_create_direct_pipeline(GstRTSPMediaFactoryWFD * factory)
1692 GstElement *src = NULL;
1693 GstElement *demux = NULL;
1694 g_autofree gchar *path = NULL;
1695 g_autofree gchar *elem_name = NULL;
1696 GstPad *srcpad = NULL;
1697 GstPad *mux_vsinkpad = NULL;
1698 GstPad *mux_asinkpad = NULL;
1699 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1700 GstRTSPMediaWFDDirectPipelineData *pipe_data = NULL;
1702 priv = factory->priv;
1703 pipe_data = priv->direct_pipe;
1705 pipe_data->pipeline = (GstBin *) gst_bin_new ("direct");
1707 src = gst_element_factory_create(priv->res.src_fact, NULL);
1708 demux = gst_element_factory_create(priv->res.demux_fact, NULL);
1709 pipe_data->ap = gst_element_factory_make ("aacparse", NULL);
1710 pipe_data->vp = gst_element_factory_make ("h264parse", NULL);
1711 pipe_data->aq = gst_element_factory_make ("queue", NULL);
1712 pipe_data->vq = gst_element_factory_make ("queue", NULL);
1713 pipe_data->tsmux = gst_element_factory_make ("mpegtsmux", NULL);
1714 pipe_data->mux_fs = gst_element_factory_make ("fakesink", NULL);
1716 if (src == NULL || demux == NULL || pipe_data->tsmux == NULL ||
1717 pipe_data->ap == NULL || pipe_data->vp == NULL ||
1718 pipe_data->aq == NULL || pipe_data->vq == NULL ||
1719 pipe_data->mux_fs == NULL) {
1720 GST_ERROR_OBJECT (factory, "Not all element created");
1724 elem_name = g_ascii_strdown(g_type_name(G_OBJECT_TYPE(src)), -1);
1726 if (g_strrstr (elem_name, "file")) {
1727 path = g_filename_from_uri (pipe_data->uri, NULL, NULL);
1730 GST_ERROR_OBJECT(factory, "No file path");
1733 g_object_set (src, "location", path, NULL);
1735 g_object_set (src, "uri", pipe_data->uri, NULL);
1737 gst_bin_add_many (pipe_data->pipeline, src, demux, pipe_data->ap,
1738 pipe_data->vp, pipe_data->aq, pipe_data->vq,
1739 pipe_data->tsmux, pipe_data->mux_fs, NULL);
1741 if (!gst_element_link (src, demux)) {
1742 GST_ERROR_OBJECT (factory, "Can't link src with demux");
1746 if (!gst_element_link (pipe_data->ap, pipe_data->aq)) {
1747 GST_ERROR_OBJECT (factory, "Can't link audio parse and queue");
1751 if (!gst_element_link (pipe_data->vp, pipe_data->vq)) {
1752 GST_ERROR_OBJECT (factory, "Can't link video parse and queue");
1756 if (!gst_element_link (pipe_data->tsmux, pipe_data->mux_fs)) {
1757 GST_DEBUG_OBJECT (factory, "Can't link muxer and fakesink");
1761 g_signal_connect_object (demux, "pad-added", G_CALLBACK (_rtsp_media_factory_wfd_demux_pad_added_cb), factory, 0);
1763 gst_bin_add (priv->stream_bin, GST_ELEMENT (pipe_data->pipeline));
1766 /* request video sink pad from muxer, which has elementary pid 0x1011 */
1767 mux_vsinkpad = gst_element_get_request_pad (pipe_data->tsmux, "sink_4113");
1768 if (!mux_vsinkpad) {
1769 GST_ERROR_OBJECT (factory, "Failed to get sink pad from muxer...");
1773 /* request srcpad from video queue */
1774 srcpad = gst_element_get_static_pad (pipe_data->vq, "src");
1776 GST_ERROR_OBJECT (factory, "Failed to get srcpad from video queue...");
1779 if (gst_pad_link (srcpad, mux_vsinkpad) != GST_PAD_LINK_OK) {
1780 GST_ERROR_OBJECT (factory, "Failed to link video queue src pad & muxer video sink pad...");
1784 gst_object_unref (mux_vsinkpad);
1785 gst_object_unref (srcpad);
1788 /* request audio sink pad from muxer, which has elementary pid 0x1100 */
1789 mux_asinkpad = gst_element_get_request_pad (pipe_data->tsmux, "sink_4352");
1790 if (!mux_asinkpad) {
1791 GST_ERROR_OBJECT (factory, "Failed to get sinkpad from muxer...");
1795 /* request srcpad from audio queue */
1796 srcpad = gst_element_get_static_pad (pipe_data->aq, "src");
1798 GST_ERROR_OBJECT (factory, "Failed to get srcpad from audio queue...");
1802 /* link audio queue's srcpad & muxer sink pad */
1803 if (gst_pad_link (srcpad, mux_asinkpad) != GST_PAD_LINK_OK) {
1804 GST_ERROR_OBJECT (factory, "Failed to link audio queue src pad & muxer audio sink pad...");
1807 gst_object_unref (mux_asinkpad);
1808 gst_object_unref (srcpad);
1811 gst_element_sync_state_with_parent (GST_ELEMENT (pipe_data->pipeline));
1813 srcpad = gst_element_get_static_pad (priv->pay, "sink");
1815 in_pad_probe = FALSE;
1816 gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_IDLE, _rtsp_media_factory_wfd_pay_pad_probe_cb, factory, NULL);
1817 gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, _rtsp_media_factory_wfd_src_pad_probe_cb, factory, NULL);
1823 _rtsp_media_factory_wfd_decodebin_element_added_cb (GstElement *decodebin,
1824 GstElement *child, void *user_data)
1826 g_autofree gchar *elem_name = g_ascii_strdown(g_type_name(G_OBJECT_TYPE(child)), -1);
1827 GstRTSPMediaFactoryWFD *factory = NULL;
1828 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1830 factory = (GstRTSPMediaFactoryWFD *) user_data;
1831 priv = factory->priv;
1833 if (g_strrstr (elem_name, "h264"))
1834 priv->res.h264_found++;
1835 if (g_strrstr (elem_name, "aac"))
1836 priv->res.aac_found++;
1837 if (g_strrstr (elem_name, "ac3"))
1838 priv->res.ac3_found++;
1839 if (g_strrstr (elem_name, "demux"))
1840 priv->res.demux_fact = gst_element_get_factory(child);
1844 _rtsp_media_factory_wfd_uridecodebin_element_added_cb (GstElement *uridecodebin,
1845 GstElement *child, void *user_data)
1847 g_autofree gchar *elem_name = g_ascii_strdown(g_type_name(G_OBJECT_TYPE(child)), -1);
1848 GstRTSPMediaFactoryWFD *factory = NULL;
1849 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1851 factory = (GstRTSPMediaFactoryWFD *) user_data;
1852 priv = factory->priv;
1854 if (g_strrstr (elem_name, "src"))
1855 priv->res.src_fact = gst_element_get_factory(child);
1857 if (G_OBJECT_TYPE(child) == priv->decodebin_type)
1858 g_signal_connect_object (child, "element-added",
1859 G_CALLBACK (_rtsp_media_factory_wfd_decodebin_element_added_cb), factory, 0);
1863 _rtsp_media_factory_wfd_discover_pad_added_cb (GstElement *uridecodebin, GstPad *pad,
1866 GstPad *sinkpad = NULL;
1869 GstElement *queue = gst_element_factory_make ("queue", NULL);
1870 GstElement *sink = gst_element_factory_make ("fakesink", NULL);
1872 if (G_UNLIKELY (queue == NULL || sink == NULL))
1875 g_object_set (sink, "silent", TRUE, NULL);
1876 g_object_set (queue, "max-size-buffers", 1, "silent", TRUE, NULL);
1878 caps = gst_pad_query_caps (pad, NULL);
1880 sinkpad = gst_element_get_static_pad (queue, "sink");
1881 if (sinkpad == NULL)
1884 gst_caps_unref (caps);
1886 gst_bin_add_many (pipeline, queue, sink, NULL);
1888 if (!gst_element_link_pads_full (queue, "src", sink, "sink",
1889 GST_PAD_LINK_CHECK_NOTHING))
1891 if (!gst_element_sync_state_with_parent (sink))
1893 if (!gst_element_sync_state_with_parent (queue))
1896 if (gst_pad_link_full (pad, sinkpad,
1897 GST_PAD_LINK_CHECK_NOTHING) != GST_PAD_LINK_OK)
1899 gst_object_unref (sinkpad);
1905 gst_object_unref (sinkpad);
1907 gst_object_unref (queue);
1909 gst_object_unref (sink);
1914 _rtsp_media_factory_wfd_uridecode_no_pad_cb (GstElement * uridecodebin, void * user_data)
1916 GstRTSPMediaFactoryWFD *factory = NULL;
1917 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1919 factory = (GstRTSPMediaFactoryWFD *) user_data;
1920 priv = factory->priv;
1921 type_detected = TRUE;
1922 g_main_loop_quit (priv->discover_loop);
1926 _rtsp_media_factory_wfd_discover_pipe_bus_call (GstBus *bus,
1930 GstRTSPMediaFactoryWFD *factory = NULL;
1931 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1933 factory = (GstRTSPMediaFactoryWFD *) data;
1934 priv = factory->priv;
1936 switch (GST_MESSAGE_TYPE (msg)) {
1937 case GST_MESSAGE_ERROR: {
1938 GError *error = NULL;
1940 gst_message_parse_error (msg, &error, NULL);
1942 GST_ERROR_OBJECT (factory, "Error: %s", error->message);
1943 g_error_free (error);
1945 type_detected = FALSE;
1946 g_main_loop_quit (priv->discover_loop);
1955 _rtsp_media_factory_wfd_find_media_type (GstRTSPMediaFactoryWFD * factory, gchar *uri)
1957 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1958 GstElement *uridecode = NULL;
1959 GstElement *tmp = NULL;
1961 GMainContext *context;
1964 priv = factory->priv;
1966 context = g_main_context_new();
1967 priv->discover_loop = g_main_loop_new(context, FALSE);
1969 tmp = gst_element_factory_make ("decodebin", NULL);
1970 priv->decodebin_type = G_OBJECT_TYPE (tmp);
1971 gst_object_unref (tmp);
1973 /* if a URI was provided, use it instead of the default one */
1974 priv->discover_pipeline = (GstBin *) gst_pipeline_new ("Discover");
1975 uridecode = gst_element_factory_make("uridecodebin", "uri");
1976 g_object_set (G_OBJECT (uridecode), "uri", uri, NULL);
1977 gst_bin_add (priv->discover_pipeline, uridecode);
1978 if (priv->decodebin_type == NULL || priv->discover_pipeline == NULL || uridecode == NULL) {
1979 GST_INFO_OBJECT (factory, "Failed to create type find pipeline");
1980 type_detected = FALSE;
1984 /* we add a message handler */
1985 bus = gst_pipeline_get_bus (GST_PIPELINE (priv->discover_pipeline));
1986 source = gst_bus_create_watch (bus);
1987 gst_bus_add_signal_watch (bus);
1989 g_source_set_callback (source, (GSourceFunc) gst_bus_async_signal_func, NULL, NULL);
1990 g_source_attach (source, context);
1991 g_signal_connect_object (bus, "message",
1992 G_CALLBACK (_rtsp_media_factory_wfd_discover_pipe_bus_call), factory, 0);
1994 g_signal_connect_object (uridecode, "pad-added",
1995 G_CALLBACK (_rtsp_media_factory_wfd_discover_pad_added_cb), priv->discover_pipeline, 0);
1996 g_signal_connect_object (uridecode, "element-added",
1997 G_CALLBACK (_rtsp_media_factory_wfd_uridecodebin_element_added_cb),
1999 g_signal_connect_object (uridecode, "no-more-pads",
2000 G_CALLBACK (_rtsp_media_factory_wfd_uridecode_no_pad_cb), factory, 0);
2001 gst_element_set_state (GST_ELEMENT (priv->discover_pipeline), GST_STATE_PLAYING);
2003 g_main_loop_run(priv->discover_loop);
2005 gst_element_set_state (GST_ELEMENT (priv->discover_pipeline), GST_STATE_NULL);
2006 g_source_destroy(source);
2007 g_source_unref (source);
2008 g_main_loop_unref(priv->discover_loop);
2009 g_main_context_unref(context);
2010 gst_object_unref(bus);
2011 gst_object_unref (GST_OBJECT (priv->discover_pipeline));
2017 gst_rtsp_media_factory_wfd_uri_type_find(GstRTSPMediaFactory *factory,
2018 gchar *filesrc, guint8 *detected_video_codec, guint8 *detected_audio_codec)
2020 GstRTSPMediaFactoryWFD *_factory = GST_RTSP_MEDIA_FACTORY_WFD_CAST (factory);
2021 GstRTSPMediaFactoryWFDPrivate *priv = _factory->priv;
2023 type_detected = FALSE;
2025 _rtsp_media_factory_wfd_find_media_type (_factory, filesrc);
2027 if (type_detected == FALSE) {
2028 GST_ERROR_OBJECT (_factory, "Media type cannot be detected");
2029 return GST_RTSP_ERROR;
2031 GST_INFO_OBJECT (_factory, "Media type detected");
2033 if (priv->res.h264_found)
2034 *detected_video_codec = GST_WFD_VIDEO_H264;
2036 if (priv->res.aac_found)
2037 *detected_audio_codec = GST_WFD_AUDIO_AAC;
2039 if (priv->res.ac3_found)
2040 *detected_audio_codec = GST_WFD_AUDIO_AC3;
2046 gst_rtsp_media_factory_wfd_set_direct_streaming(GstRTSPMediaFactory * factory,
2047 gint direct_streaming, gchar *filesrc)
2049 GstRTSPMediaFactoryWFD *_factory = GST_RTSP_MEDIA_FACTORY_WFD_CAST (factory);
2052 if (direct_streaming == 0) {
2053 if (!_rtsp_media_factory_wfd_relink_pipeline(_factory)) {
2054 GST_ERROR_OBJECT (factory, "Failed to relink pipeline");
2055 return GST_RTSP_ERROR;
2058 _rtsp_media_factory_wfd_destroy_direct_pipe ((void *)_factory);
2060 GST_INFO_OBJECT (_factory, "Direct streaming bin removed");
2065 _factory->priv->direct_pipe = g_new0 (GstRTSPMediaWFDDirectPipelineData, 1);
2066 _factory->priv->direct_pipe->uri = g_strdup(filesrc);
2068 if (!_rtsp_media_factory_wfd_create_direct_pipeline(_factory)) {
2069 GST_ERROR_OBJECT (_factory, "Direct pipeline creation failed");
2070 return GST_RTSP_ERROR;
2073 g_mutex_lock (&_factory->priv->direct_lock);
2074 while (linked != TRUE) {
2075 gint64 end_time = g_get_monotonic_time () + 5 * G_TIME_SPAN_SECOND;
2076 if (!g_cond_wait_until (&_factory->priv->direct_cond, &_factory->priv->direct_lock, end_time)) {
2077 g_mutex_unlock (&_factory->priv->direct_lock);
2078 GST_ERROR_OBJECT (_factory, "Direct pipeline linking failed");
2079 return GST_RTSP_ERROR;
2082 g_mutex_unlock (&_factory->priv->direct_lock);
2084 GST_INFO_OBJECT (_factory, "Direct streaming bin created");