2 * Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.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)
40 #include "rtsp-media-factory-wfd.h"
41 #include "gstwfdmessage.h"
43 #define GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE(obj) \
44 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTSP_MEDIA_FACTORY_WFD, GstRTSPMediaFactoryWFDPrivate))
46 #define GST_RTSP_MEDIA_FACTORY_WFD_GET_LOCK(f) (&(GST_RTSP_MEDIA_FACTORY_WFD_CAST(f)->priv->lock))
47 #define GST_RTSP_MEDIA_FACTORY_WFD_LOCK(f) (g_mutex_lock(GST_RTSP_MEDIA_FACTORY_WFD_GET_LOCK(f)))
48 #define GST_RTSP_MEDIA_FACTORY_WFD_UNLOCK(f) (g_mutex_unlock(GST_RTSP_MEDIA_FACTORY_WFD_GET_LOCK(f)))
50 struct _GstRTSPMediaFactoryWFDPrivate
53 GstRTSPPermissions *permissions;
56 GstRTSPLowerTrans protocols;
65 guint video_framerate;
66 guint video_enc_skip_inbuf_value;
67 GstElement *video_queue;
71 guint64 audio_latency_time;
72 guint64 audio_buffer_time;
73 gboolean audio_do_timestamp;
74 guint8 audio_channels;
77 GstElement *audio_queue;
79 guint64 video_resolution_supported;
84 #define DEFAULT_LAUNCH NULL
85 #define DEFAULT_SHARED FALSE
86 #define DEFAULT_PROTOCOLS GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_UDP_MCAST | \
87 GST_RTSP_LOWER_TRANS_TCP
88 #define DEFAULT_BUFFER_SIZE 0x80000
104 SIGNAL_MEDIA_CONSTRUCTED,
105 SIGNAL_MEDIA_CONFIGURE,
109 GST_DEBUG_CATEGORY_STATIC (rtsp_media_wfd_debug);
110 #define GST_CAT_DEFAULT rtsp_media_wfd_debug
112 static void gst_rtsp_media_factory_wfd_get_property (GObject * object,
113 guint propid, GValue * value, GParamSpec * pspec);
114 static void gst_rtsp_media_factory_wfd_set_property (GObject * object,
115 guint propid, const GValue * value, GParamSpec * pspec);
117 static void gst_rtsp_media_factory_wfd_finalize (GObject * obj);
120 static GstElement *rtsp_media_factory_wfd_create_element (GstRTSPMediaFactory *
121 factory, const GstRTSPUrl * url);
122 static GstRTSPMedia *rtsp_media_factory_wfd_construct (GstRTSPMediaFactory *
123 factory, const GstRTSPUrl * url);
125 G_DEFINE_TYPE (GstRTSPMediaFactoryWFD, gst_rtsp_media_factory_wfd,
126 GST_TYPE_RTSP_MEDIA_FACTORY);
129 gst_rtsp_media_factory_wfd_class_init (GstRTSPMediaFactoryWFDClass * klass)
131 GObjectClass *gobject_class;
132 GstRTSPMediaFactoryClass *factory_class;
134 g_type_class_add_private (klass, sizeof (GstRTSPMediaFactoryWFDPrivate));
136 gobject_class = G_OBJECT_CLASS (klass);
137 factory_class = GST_RTSP_MEDIA_FACTORY_CLASS (klass);
139 gobject_class->get_property = gst_rtsp_media_factory_wfd_get_property;
140 gobject_class->set_property = gst_rtsp_media_factory_wfd_set_property;
141 gobject_class->finalize = gst_rtsp_media_factory_wfd_finalize;
143 factory_class->construct = rtsp_media_factory_wfd_construct;
144 factory_class->create_element = rtsp_media_factory_wfd_create_element;
146 GST_DEBUG_CATEGORY_INIT (rtsp_media_wfd_debug, "rtspmediafactorywfd", 0,
147 "GstRTSPMediaFactoryWFD");
150 void gst_rtsp_media_factory_wfd_set (GstRTSPMediaFactoryWFD * factory,
151 guint8 videosrc_type, gchar *audio_device, guint64 audio_latency_time,
152 guint64 audio_buffer_time, gboolean audio_do_timestamp, guint mtu_size)
154 GstRTSPMediaFactoryWFDPrivate *priv =
155 GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE (factory);
156 factory->priv = priv;
158 priv->videosrc_type = videosrc_type;
159 priv->audio_device= audio_device;
160 priv->audio_latency_time = audio_latency_time;
161 priv->audio_buffer_time = audio_buffer_time;
162 priv->audio_do_timestamp = audio_do_timestamp;
163 priv->mtu_size = mtu_size;
166 void gst_rtsp_media_factory_wfd_set_dump_ts (GstRTSPMediaFactoryWFD * factory,
169 GstRTSPMediaFactoryWFDPrivate *priv =
170 GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE (factory);
171 factory->priv = priv;
173 priv->dump_ts = dump_ts;
175 void gst_rtsp_media_factory_wfd_set_negotiated_resolution (GstRTSPMediaFactory *factory,
176 guint32 width, guint32 height)
178 GstRTSPMediaFactoryWFD *factory_wfd = GST_RTSP_MEDIA_FACTORY_WFD (factory);
179 GstRTSPMediaFactoryWFDPrivate *priv = factory_wfd->priv;
181 priv->video_width = width;
182 priv->video_height = height;
186 gst_rtsp_media_factory_wfd_init (GstRTSPMediaFactoryWFD * factory)
188 GstRTSPMediaFactoryWFDPrivate *priv =
189 GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE (factory);
190 factory->priv = priv;
192 priv->launch = g_strdup (DEFAULT_LAUNCH);
193 priv->shared = DEFAULT_SHARED;
194 priv->protocols = DEFAULT_PROTOCOLS;
195 priv->buffer_size = DEFAULT_BUFFER_SIZE;
197 //priv->videosrc_type = GST_WFD_VSRC_XIMAGESRC;
198 //priv->videosrc_type = GST_WFD_VSRC_XVIMAGESRC;
199 //priv->videosrc_type = GST_WFD_VSRC_CAMERASRC;
200 priv->videosrc_type = GST_WFD_VSRC_VIDEOTESTSRC;
201 priv->video_codec = GST_WFD_VIDEO_H264;
202 priv->video_bitrate = 200000;
203 priv->video_width = 640;
204 priv->video_height = 480;
205 priv->video_framerate = 30;
206 priv->video_enc_skip_inbuf_value = 5;
208 priv->audio_device = g_strdup ("alsa_output.1.analog-stereo.monitor");
209 priv->audio_codec = GST_WFD_AUDIO_AAC;
210 priv->audio_latency_time = 10000;
211 priv->audio_buffer_time = 200000;
212 priv->audio_do_timestamp = FALSE;
213 priv->audio_channels = GST_WFD_CHANNEL_2;
214 priv->audio_freq = GST_WFD_FREQ_48000;
216 g_mutex_init (&priv->lock);
220 gst_rtsp_media_factory_wfd_finalize (GObject * obj)
222 GstRTSPMediaFactoryWFD *factory = GST_RTSP_MEDIA_FACTORY_WFD (obj);
223 GstRTSPMediaFactoryWFDPrivate *priv = factory->priv;
225 if (priv->permissions)
226 gst_rtsp_permissions_unref (priv->permissions);
227 g_free (priv->launch);
228 g_mutex_clear (&priv->lock);
230 if (priv->audio_device)
231 g_free (priv->audio_device);
233 G_OBJECT_CLASS (gst_rtsp_media_factory_wfd_parent_class)->finalize (obj);
236 GstRTSPMediaFactoryWFD *
237 gst_rtsp_media_factory_wfd_new (void)
239 GstRTSPMediaFactoryWFD *result;
241 result = g_object_new (GST_TYPE_RTSP_MEDIA_FACTORY_WFD, NULL);
247 gst_rtsp_media_factory_wfd_get_property (GObject * object,
248 guint propid, GValue * value, GParamSpec * pspec)
250 //GstRTSPMediaFactoryWFD *factory = GST_RTSP_MEDIA_FACTORY_WFD (object);
254 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
259 gst_rtsp_media_factory_wfd_set_property (GObject * object,
260 guint propid, const GValue * value, GParamSpec * pspec)
262 //GstRTSPMediaFactoryWFD *factory = GST_RTSP_MEDIA_FACTORY_WFD (object);
266 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
270 static GstPadProbeReturn
271 rtsp_media_wfd_dump_data (GstPad * pad, GstPadProbeInfo *info, gpointer u_data)
278 if (info->type == (GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_PUSH)) {
279 GstBuffer *buffer = gst_pad_probe_info_get_buffer (info);
281 gst_buffer_map (buffer, &mapinfo, GST_MAP_READ);
283 size = gst_buffer_get_size (buffer);
285 f = fopen ("/root/probe.ts", "a");
286 fwrite (data, size, 1, f);
288 gst_buffer_unmap (buffer, &mapinfo);
291 return GST_PAD_PROBE_OK;
295 _rtsp_media_factory_wfd_create_audio_capture_bin (GstRTSPMediaFactoryWFD *
296 factory, GstBin * srcbin)
298 GstElement *audiosrc = NULL;
299 GstElement *acaps = NULL;
300 GstElement *aenc = NULL;
301 GstElement *audio_convert = NULL;
302 GstElement *aqueue = NULL;
303 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
306 gboolean is_enc_req = TRUE;
308 gchar *acodec = NULL;
310 priv = factory->priv;
312 /* create audio src element */
313 audiosrc = gst_element_factory_make ("pulsesrc", "audiosrc");
315 GST_ERROR_OBJECT (factory, "failed to create audiosrc element");
319 GST_INFO_OBJECT (factory, "audio device : %s", priv->audio_device);
320 GST_INFO_OBJECT (factory, "audio latency time : %lld",
321 priv->audio_latency_time);
322 GST_INFO_OBJECT (factory, "audio_buffer_time : %lld",
323 priv->audio_buffer_time);
324 GST_INFO_OBJECT (factory, "audio_do_timestamp : %d",
325 priv->audio_do_timestamp);
327 g_object_set (audiosrc, "device", priv->audio_device, NULL);
328 g_object_set (audiosrc, "buffer-time", (gint64) priv->audio_buffer_time,
330 g_object_set (audiosrc, "latency-time", (gint64) priv->audio_latency_time,
332 g_object_set (audiosrc, "do-timestamp", (gboolean) priv->audio_do_timestamp,
334 g_object_set (audiosrc, "provide-clock", (gboolean) FALSE, NULL);
335 g_object_set (audiosrc, "is-live", (gboolean) TRUE, NULL);
337 if (priv->audio_codec == GST_WFD_AUDIO_LPCM) {
338 /* To meet miracast certification */
339 gint64 block_size = 1920;
340 g_object_set (audiosrc, "blocksize", (gint64) block_size, NULL);
342 audio_convert = gst_element_factory_make ("audioconvert", "audio_convert");
343 if (NULL == audio_convert) {
344 GST_ERROR_OBJECT (factory, "failed to create audio convert element");
349 /* create audio caps element */
350 acaps = gst_element_factory_make ("capsfilter", "audiocaps");
352 GST_ERROR_OBJECT (factory, "failed to create audio capsilfter element");
356 if (priv->audio_channels == GST_WFD_CHANNEL_2)
358 else if (priv->audio_channels == GST_WFD_CHANNEL_4)
360 else if (priv->audio_channels == GST_WFD_CHANNEL_6)
362 else if (priv->audio_channels == GST_WFD_CHANNEL_8)
367 if (priv->audio_freq == GST_WFD_FREQ_44100)
369 else if (priv->audio_freq == GST_WFD_FREQ_48000)
374 if (priv->audio_codec == GST_WFD_AUDIO_LPCM) {
375 g_object_set (G_OBJECT (acaps), "caps",
376 gst_caps_new_simple ("audio/x-lpcm", "width", G_TYPE_INT, 16,
377 /* In case of LPCM, uses big endian */
378 "endianness", G_TYPE_INT, 4321,
379 "signed", G_TYPE_BOOLEAN, TRUE,
380 "depth", G_TYPE_INT, 16,
381 "rate", G_TYPE_INT, freq,
382 "channels", G_TYPE_INT, channels, NULL), NULL);
383 } else if ((priv->audio_codec == GST_WFD_AUDIO_AAC)
384 || (priv->audio_codec == GST_WFD_AUDIO_AC3)) {
385 g_object_set (G_OBJECT (acaps), "caps", gst_caps_new_simple ("audio/x-raw",
386 "endianness", G_TYPE_INT, 1234, "signed", G_TYPE_BOOLEAN, TRUE,
387 "depth", G_TYPE_INT, 16, "rate", G_TYPE_INT, freq, "channels",
388 G_TYPE_INT, channels, NULL), NULL);
391 if (priv->audio_codec == GST_WFD_AUDIO_AAC) {
392 acodec = g_strdup ("avenc_aac");
394 } else if (priv->audio_codec == GST_WFD_AUDIO_AC3) {
395 acodec = g_strdup ("avenc_ac3");
397 } else if (priv->audio_codec == GST_WFD_AUDIO_LPCM) {
398 GST_DEBUG_OBJECT (factory, "No codec required, raw data will be sent");
401 GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
406 aenc = gst_element_factory_make (acodec, "audioenc");
408 GST_ERROR_OBJECT (factory, "failed to create audio encoder element");
412 g_object_set (aenc, "compliance", -2, NULL);
413 g_object_set (aenc, "tolerance", 400000000, NULL);
414 g_object_set (aenc, "bitrate", (guint) 128000, NULL);
415 g_object_set (aenc, "rate-control", 2, NULL);
417 aqueue = gst_element_factory_make ("queue", "audio-queue");
419 GST_ERROR_OBJECT (factory, "failed to create audio queue element");
423 gst_bin_add_many (srcbin, audiosrc, acaps, aenc, aqueue, NULL);
425 if (!gst_element_link_many (audiosrc, acaps, aenc, aqueue, NULL)) {
426 GST_ERROR_OBJECT (factory, "Failed to link audio src elements...");
430 aqueue = gst_element_factory_make ("queue", "audio-queue");
432 GST_ERROR_OBJECT (factory, "failed to create audio queue element");
436 gst_bin_add_many (srcbin, audiosrc, audio_convert, acaps, aqueue, NULL);
438 if (!gst_element_link_many (audiosrc, audio_convert, acaps, aqueue, NULL)) {
439 GST_ERROR_OBJECT (factory, "Failed to link audio src elements...");
444 priv->audio_queue = aqueue;
453 _rtsp_media_factory_wfd_create_videotest_bin (GstRTSPMediaFactoryWFD * factory,
456 GstElement *videosrc = NULL;
457 GstElement *vcaps = NULL;
458 GstElement *venc_caps = NULL;
459 gchar *vcodec = NULL;
460 GstElement *venc = NULL;
461 GstElement *vqueue = NULL;
462 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
464 priv = factory->priv;
466 GST_INFO_OBJECT (factory, "picked videotestsrc as video source");
468 videosrc = gst_element_factory_make ("videotestsrc", "videosrc");
469 if (NULL == videosrc) {
470 GST_ERROR_OBJECT (factory, "failed to create ximagesrc element");
474 /* create video caps element */
475 vcaps = gst_element_factory_make ("capsfilter", "videocaps");
477 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
481 g_object_set (G_OBJECT (vcaps), "caps",
482 gst_caps_new_simple ("video/x-raw",
483 "width", G_TYPE_INT, priv->video_width,
484 "height", G_TYPE_INT, priv->video_height,
485 "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
488 if (priv->video_codec == GST_WFD_VIDEO_H264)
489 vcodec = g_strdup ("x264enc");
491 GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
496 venc = gst_element_factory_make (vcodec, "videoenc");
500 GST_ERROR_OBJECT (factory, "failed to create video encoder element");
504 g_object_set (venc, "aud", 0, NULL);
505 g_object_set (venc, "byte-stream", 1, NULL);
506 g_object_set (venc, "bitrate", 512, NULL);
508 venc_caps = gst_element_factory_make ("capsfilter", "venc_caps");
509 if (NULL == venc_caps) {
510 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
514 g_object_set (G_OBJECT (venc_caps), "caps",
515 gst_caps_new_simple ("video/x-h264",
516 "profile", G_TYPE_STRING, "baseline", NULL), NULL);
518 vqueue = gst_element_factory_make ("queue", "video-queue");
520 GST_ERROR_OBJECT (factory, "failed to create video queue element");
524 gst_bin_add_many (srcbin, videosrc, vcaps, venc, venc_caps, vqueue, NULL);
525 if (!gst_element_link_many (videosrc, vcaps, venc, venc_caps, vqueue, NULL)) {
526 GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
530 priv->video_queue = vqueue;
539 _rtsp_media_factory_wfd_create_camera_capture_bin (GstRTSPMediaFactoryWFD *
540 factory, GstBin * srcbin)
542 GstElement *videosrc = NULL;
543 GstElement *vcaps = NULL;
544 GstElement *venc = NULL;
545 GstElement *vqueue = NULL;
546 gchar *vcodec = NULL;
547 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
549 priv = factory->priv;
551 videosrc = gst_element_factory_make ("camerasrc", "videosrc");
552 if (NULL == videosrc) {
553 GST_ERROR_OBJECT (factory, "failed to create camerasrc element");
557 /* create video caps element */
558 vcaps = gst_element_factory_make ("capsfilter", "videocaps");
560 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
564 GST_INFO_OBJECT (factory, "picked camerasrc as video source");
565 g_object_set (G_OBJECT (vcaps), "caps",
566 gst_caps_new_simple ("video/x-raw",
567 "width", G_TYPE_INT, priv->video_width,
568 "height", G_TYPE_INT, priv->video_height,
569 "format", G_TYPE_STRING, "SN12",
570 "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
573 if (priv->video_codec == GST_WFD_VIDEO_H264)
574 vcodec = g_strdup ("omxh264enc");
576 GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
580 venc = gst_element_factory_make (vcodec, "videoenc");
582 GST_ERROR_OBJECT (factory, "failed to create video encoder element");
586 g_object_set (venc, "bitrate", priv->video_bitrate, NULL);
587 g_object_set (venc, "byte-stream", 1, NULL);
588 g_object_set (venc, "append-dci", 1, NULL);
590 vqueue = gst_element_factory_make ("queue", "video-queue");
592 GST_ERROR_OBJECT (factory, "failed to create video queue element");
596 gst_bin_add_many (srcbin, videosrc, vcaps, venc, vqueue, NULL);
598 if (!gst_element_link_many (videosrc, vcaps, venc, vqueue, NULL)) {
599 GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
603 priv->video_queue = vqueue;
612 _rtsp_media_factory_wfd_create_xcapture_bin (GstRTSPMediaFactoryWFD * factory,
615 GstElement *videosrc = NULL;
616 GstElement *vcaps = NULL;
617 GstElement *venc_caps = NULL;
618 GstElement *videoconvert = NULL, *videoscale = NULL;
619 gchar *vcodec = NULL;
620 GstElement *venc = NULL;
621 GstElement *vqueue = NULL;
622 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
624 priv = factory->priv;
626 GST_INFO_OBJECT (factory, "picked ximagesrc as video source");
628 videosrc = gst_element_factory_make ("ximagesrc", "videosrc");
629 if (NULL == videosrc) {
630 GST_ERROR_OBJECT (factory, "failed to create ximagesrc element");
634 videoscale = gst_element_factory_make ("videoscale", "videoscale");
635 if (NULL == videoscale) {
636 GST_ERROR_OBJECT (factory, "failed to create videoscale element");
640 videoconvert = gst_element_factory_make ("videoconvert", "videoconvert");
641 if (NULL == videoconvert) {
642 GST_ERROR_OBJECT (factory, "failed to create videoconvert element");
646 /* create video caps element */
647 vcaps = gst_element_factory_make ("capsfilter", "videocaps");
649 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
653 g_object_set (G_OBJECT (vcaps), "caps",
654 gst_caps_new_simple ("video/x-raw",
655 "width", G_TYPE_INT, priv->video_width,
656 "height", G_TYPE_INT, priv->video_height,
657 "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
660 if (priv->video_codec == GST_WFD_VIDEO_H264)
661 vcodec = g_strdup ("x264enc");
663 GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
668 venc = gst_element_factory_make (vcodec, "videoenc");
672 GST_ERROR_OBJECT (factory, "failed to create video encoder element");
676 g_object_set (venc, "aud", 0, NULL);
677 g_object_set (venc, "byte-stream", 1, NULL);
678 g_object_set (venc, "bitrate", 512, NULL);
680 venc_caps = gst_element_factory_make ("capsfilter", "venc_caps");
681 if (NULL == venc_caps) {
682 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
686 g_object_set (G_OBJECT (venc_caps), "caps",
687 gst_caps_new_simple ("video/x-h264",
688 "profile", G_TYPE_STRING, "baseline", NULL), NULL);
690 vqueue = gst_element_factory_make ("queue", "video-queue");
692 GST_ERROR_OBJECT (factory, "failed to create video queue element");
696 gst_bin_add_many (srcbin, videosrc, videoscale, videoconvert, vcaps, venc,
697 venc_caps, vqueue, NULL);
698 if (!gst_element_link_many (videosrc, videoscale, videoconvert, vcaps, venc,
699 venc_caps, vqueue, NULL)) {
700 GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
704 priv->video_queue = vqueue;
713 _rtsp_media_factory_wfd_create_xvcapture_bin (GstRTSPMediaFactoryWFD * factory,
716 GstElement *videosrc = NULL;
717 GstElement *vcaps = NULL;
718 gchar *vcodec = NULL;
719 GstElement *venc = NULL;
720 GstElement *vqueue = NULL;
721 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
723 priv = factory->priv;
725 GST_INFO_OBJECT (factory, "picked xvimagesrc as video source");
727 videosrc = gst_element_factory_make ("xvimagesrc", "videosrc");
728 if (NULL == videosrc) {
729 GST_ERROR_OBJECT (factory, "failed to create xvimagesrc element");
733 /* create video caps element */
734 vcaps = gst_element_factory_make ("capsfilter", "videocaps");
736 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
740 g_object_set (G_OBJECT (vcaps), "caps",
741 gst_caps_new_simple ("video/x-raw",
742 "width", G_TYPE_INT, priv->video_width,
743 "height", G_TYPE_INT, priv->video_height,
744 "format", G_TYPE_STRING, "SN12",
745 "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
748 if (priv->video_codec == GST_WFD_VIDEO_H264) {
749 vcodec = g_strdup ("omxh264enc");
751 GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
755 venc = gst_element_factory_make (vcodec, "videoenc");
757 GST_ERROR_OBJECT (factory, "failed to create video encoder element");
760 g_object_set (venc, "bitrate", priv->video_bitrate, NULL);
761 g_object_set (venc, "byte-stream", 1, NULL);
762 g_object_set (venc, "append-dci", 1, NULL);
763 g_object_set (venc, "idr-period", 120, NULL);
764 g_object_set (venc, "skip-inbuf", priv->video_enc_skip_inbuf_value, NULL);
766 vqueue = gst_element_factory_make ("queue", "video-queue");
768 GST_ERROR_OBJECT (factory, "failed to create video queue element");
772 gst_bin_add_many (srcbin, videosrc, vcaps, venc, vqueue, NULL);
773 if (!gst_element_link_many (videosrc, vcaps, venc, vqueue, NULL)) {
774 GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
778 priv->video_queue = vqueue;
787 _rtsp_media_factory_wfd_create_srcbin (GstRTSPMediaFactoryWFD * factory)
789 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
791 GstBin *srcbin = NULL;
792 GstElement *mux = NULL;
793 GstElement *mux_queue = NULL;
794 GstElement *payload = NULL;
795 GstPad *srcpad = NULL;
796 GstPad *mux_vsinkpad = NULL;
797 GstPad *mux_asinkpad = NULL;
799 priv = factory->priv;
801 /* create source bin */
802 srcbin = GST_BIN (gst_bin_new ("srcbin"));
804 GST_ERROR_OBJECT (factory, "failed to create source bin...");
808 /* create video src element */
809 switch (priv->videosrc_type) {
810 case GST_WFD_VSRC_XIMAGESRC:
811 if (!_rtsp_media_factory_wfd_create_xcapture_bin (factory, srcbin)) {
812 GST_ERROR_OBJECT (factory, "failed to create xcapture bin...");
816 case GST_WFD_VSRC_XVIMAGESRC:
817 if (!_rtsp_media_factory_wfd_create_xvcapture_bin (factory, srcbin)) {
818 GST_ERROR_OBJECT (factory, "failed to create xvcapture bin...");
822 case GST_WFD_VSRC_CAMERASRC:
823 if (!_rtsp_media_factory_wfd_create_camera_capture_bin (factory, srcbin)) {
824 GST_ERROR_OBJECT (factory, "failed to create camera capture bin...");
828 case GST_WFD_VSRC_VIDEOTESTSRC:
829 if (!_rtsp_media_factory_wfd_create_videotest_bin (factory, srcbin)) {
830 GST_ERROR_OBJECT (factory, "failed to create videotestsrc bin...");
835 GST_ERROR_OBJECT (factory, "unknow mode selected...");
839 mux = gst_element_factory_make ("mpegtsmux", "tsmux");
841 GST_ERROR_OBJECT (factory, "failed to create muxer element");
845 g_object_set (mux, "wfd-mode", TRUE, NULL);
847 mux_queue = gst_element_factory_make ("queue", "muxer-queue");
849 GST_ERROR_OBJECT (factory, "failed to create muxer-queue element");
853 g_object_set (mux_queue, "max-size-buffers", 20000, NULL);
855 payload = gst_element_factory_make ("rtpmp2tpay", "pay0");
857 GST_ERROR_OBJECT (factory, "failed to create payload element");
861 g_object_set (payload, "pt", 33, NULL);
862 g_object_set (payload, "mtu", priv->mtu_size, NULL);
863 g_object_set (payload, "rtp-flush", (gboolean) TRUE, NULL);
865 gst_bin_add_many (srcbin, mux, mux_queue, payload, NULL);
867 if (!gst_element_link_many (mux, mux_queue, payload, NULL)) {
868 GST_ERROR_OBJECT (factory, "Failed to link muxer & payload...");
872 /* request video sink pad from muxer, which has elementary pid 0x1011 */
873 mux_vsinkpad = gst_element_get_request_pad (mux, "sink_4113");
875 GST_ERROR_OBJECT (factory, "Failed to get sink pad from muxer...");
879 /* request srcpad from video queue */
880 srcpad = gst_element_get_static_pad (priv->video_queue, "src");
882 GST_ERROR_OBJECT (factory, "Failed to get srcpad from video queue...");
886 if (gst_pad_link (srcpad, mux_vsinkpad) != GST_PAD_LINK_OK) {
887 GST_ERROR_OBJECT (factory,
888 "Failed to link video queue src pad & muxer video sink pad...");
892 gst_object_unref (mux_vsinkpad);
893 gst_object_unref (srcpad);
896 /* create audio source elements & add to pipeline */
897 if (!_rtsp_media_factory_wfd_create_audio_capture_bin (factory, srcbin))
900 /* request audio sink pad from muxer, which has elementary pid 0x1100 */
901 mux_asinkpad = gst_element_get_request_pad (mux, "sink_4352");
903 GST_ERROR_OBJECT (factory, "Failed to get sinkpad from muxer...");
907 /* request srcpad from audio queue */
908 srcpad = gst_element_get_static_pad (priv->audio_queue, "src");
910 GST_ERROR_OBJECT (factory, "Failed to get srcpad from audio queue...");
914 /* link audio queue's srcpad & muxer sink pad */
915 if (gst_pad_link (srcpad, mux_asinkpad) != GST_PAD_LINK_OK) {
916 GST_ERROR_OBJECT (factory,
917 "Failed to link audio queue src pad & muxer audio sink pad...");
920 gst_object_unref (mux_asinkpad);
921 gst_object_unref (srcpad);
925 GstPad *pad_probe = NULL;
926 pad_probe = gst_element_get_static_pad (mux, "src");
928 if (NULL == pad_probe) {
929 GST_INFO_OBJECT (factory, "pad for probe not created");
931 GST_INFO_OBJECT (factory, "pad for probe SUCCESSFUL");
933 gst_pad_add_probe (pad_probe, GST_PAD_PROBE_TYPE_BUFFER,
934 rtsp_media_wfd_dump_data, factory, NULL);
937 GST_DEBUG_OBJECT (factory, "successfully created source bin...");
939 return GST_ELEMENT_CAST (srcbin);
942 GST_ERROR_OBJECT (factory, "Failed to create pipeline");
947 rtsp_media_factory_wfd_create_element (GstRTSPMediaFactory * factory,
948 const GstRTSPUrl * url)
950 GstRTSPMediaFactoryWFD *_factory = GST_RTSP_MEDIA_FACTORY_WFD_CAST (factory);
951 GstElement *element = NULL;
953 GST_RTSP_MEDIA_FACTORY_WFD_LOCK (factory);
955 element = _rtsp_media_factory_wfd_create_srcbin (_factory);
957 GST_RTSP_MEDIA_FACTORY_WFD_UNLOCK (factory);
962 static GstRTSPMedia *
963 rtsp_media_factory_wfd_construct (GstRTSPMediaFactory * factory,
964 const GstRTSPUrl * url)
967 GstElement *element, *pipeline;
968 GstRTSPMediaFactoryClass *klass;
970 klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
972 if (!klass->create_pipeline)
975 element = gst_rtsp_media_factory_create_element (factory, url);
979 /* create a new empty media */
980 media = gst_rtsp_media_new (element);
982 gst_rtsp_media_collect_streams (media);
984 pipeline = klass->create_pipeline (factory, media);
985 if (pipeline == NULL)
993 g_critical ("no create_pipeline function");
998 g_critical ("could not create element");
1003 g_critical ("can't create pipeline");
1004 g_object_unref (media);