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)
40 #include "rtsp-media-factory-wfd.h"
41 #include "gstwfdmessage.h"
42 #include "rtsp-media-ext.h"
44 #define GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE(obj) \
45 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTSP_MEDIA_FACTORY_WFD, GstRTSPMediaFactoryWFDPrivate))
47 #define GST_RTSP_MEDIA_FACTORY_WFD_GET_LOCK(f) (&(GST_RTSP_MEDIA_FACTORY_WFD_CAST(f)->priv->lock))
48 #define GST_RTSP_MEDIA_FACTORY_WFD_LOCK(f) (g_mutex_lock(GST_RTSP_MEDIA_FACTORY_WFD_GET_LOCK(f)))
49 #define GST_RTSP_MEDIA_FACTORY_WFD_UNLOCK(f) (g_mutex_unlock(GST_RTSP_MEDIA_FACTORY_WFD_GET_LOCK(f)))
51 struct _GstRTSPMediaFactoryWFDPrivate
54 GstRTSPPermissions *permissions;
57 GstRTSPLowerTrans protocols;
67 guint video_framerate;
68 guint video_enc_skip_inbuf_value;
69 GstElement *video_queue;
72 guint decide_udp_bitrate[21];
73 guint min_udp_bitrate;
74 guint max_udp_bitrate;
75 gboolean decided_udp_bitrate;
78 gchar *audio_encoder_aac;
79 gchar *audio_encoder_ac3;
81 guint64 audio_latency_time;
82 guint64 audio_buffer_time;
83 gboolean audio_do_timestamp;
84 guint8 audio_channels;
87 GstElement *audio_queue;
89 guint64 video_resolution_supported;
94 #define DEFAULT_LAUNCH NULL
95 #define DEFAULT_SHARED FALSE
96 #define DEFAULT_PROTOCOLS GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_UDP_MCAST | \
97 GST_RTSP_LOWER_TRANS_TCP
98 #define DEFAULT_BUFFER_SIZE 0x80000
114 SIGNAL_MEDIA_CONSTRUCTED,
115 SIGNAL_MEDIA_CONFIGURE,
119 GST_DEBUG_CATEGORY_STATIC (rtsp_media_wfd_debug);
120 #define GST_CAT_DEFAULT rtsp_media_wfd_debug
122 static void gst_rtsp_media_factory_wfd_get_property (GObject * object,
123 guint propid, GValue * value, GParamSpec * pspec);
124 static void gst_rtsp_media_factory_wfd_set_property (GObject * object,
125 guint propid, const GValue * value, GParamSpec * pspec);
127 static void gst_rtsp_media_factory_wfd_finalize (GObject * obj);
130 static GstElement *rtsp_media_factory_wfd_create_element (GstRTSPMediaFactory *
131 factory, const GstRTSPUrl * url);
132 static GstRTSPMedia *rtsp_media_factory_wfd_construct (GstRTSPMediaFactory *
133 factory, const GstRTSPUrl * url);
135 static void _config_bitrate (GstRTSPMediaFactoryWFD * factory);
137 G_DEFINE_TYPE (GstRTSPMediaFactoryWFD, gst_rtsp_media_factory_wfd,
138 GST_TYPE_RTSP_MEDIA_FACTORY);
141 gst_rtsp_media_factory_wfd_class_init (GstRTSPMediaFactoryWFDClass * klass)
143 GObjectClass *gobject_class;
144 GstRTSPMediaFactoryClass *factory_class;
146 g_type_class_add_private (klass, sizeof (GstRTSPMediaFactoryWFDPrivate));
148 gobject_class = G_OBJECT_CLASS (klass);
149 factory_class = GST_RTSP_MEDIA_FACTORY_CLASS (klass);
151 gobject_class->get_property = gst_rtsp_media_factory_wfd_get_property;
152 gobject_class->set_property = gst_rtsp_media_factory_wfd_set_property;
153 gobject_class->finalize = gst_rtsp_media_factory_wfd_finalize;
155 factory_class->construct = rtsp_media_factory_wfd_construct;
156 factory_class->create_element = rtsp_media_factory_wfd_create_element;
158 GST_DEBUG_CATEGORY_INIT (rtsp_media_wfd_debug, "rtspmediafactorywfd", 0,
159 "GstRTSPMediaFactoryWFD");
163 gst_rtsp_media_factory_wfd_set (GstRTSPMediaFactoryWFD * factory,
164 guint8 videosrc_type, gchar * audio_device, guint64 audio_latency_time,
165 guint64 audio_buffer_time, gboolean audio_do_timestamp, guint mtu_size)
167 GstRTSPMediaFactoryWFDPrivate *priv =
168 GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE (factory);
169 factory->priv = priv;
171 priv->videosrc_type = videosrc_type;
172 priv->audio_device = audio_device;
173 priv->audio_latency_time = audio_latency_time;
174 priv->audio_buffer_time = audio_buffer_time;
175 priv->audio_do_timestamp = audio_do_timestamp;
176 priv->mtu_size = mtu_size;
180 gst_rtsp_media_factory_wfd_set_encoders (GstRTSPMediaFactoryWFD * factory,
181 gchar * video_encoder, gchar * audio_encoder_aac, gchar * audio_encoder_ac3)
183 GstRTSPMediaFactoryWFDPrivate *priv =
184 GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE (factory);
185 factory->priv = priv;
187 priv->video_encoder = video_encoder;
188 priv->audio_encoder_aac = audio_encoder_aac;
189 priv->audio_encoder_ac3 = audio_encoder_ac3;
193 gst_rtsp_media_factory_wfd_set_dump_ts (GstRTSPMediaFactoryWFD * factory,
196 GstRTSPMediaFactoryWFDPrivate *priv =
197 GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE (factory);
198 factory->priv = priv;
200 priv->dump_ts = dump_ts;
204 gst_rtsp_media_factory_wfd_set_negotiated_resolution (GstRTSPMediaFactory *
205 factory, guint32 width, guint32 height)
207 GstRTSPMediaFactoryWFD *factory_wfd = GST_RTSP_MEDIA_FACTORY_WFD (factory);
208 GstRTSPMediaFactoryWFDPrivate *priv = factory_wfd->priv;
210 priv->video_width = width;
211 priv->video_height = height;
212 _config_bitrate (factory_wfd);
216 gst_rtsp_media_factory_wfd_set_audio_codec (GstRTSPMediaFactory * factory,
219 GstRTSPMediaFactoryWFD *factory_wfd = GST_RTSP_MEDIA_FACTORY_WFD (factory);
220 GstRTSPMediaFactoryWFDPrivate *priv = factory_wfd->priv;
222 priv->audio_codec = audio_codec;
226 _config_bitrate (GstRTSPMediaFactoryWFD * factory)
228 GstRTSPMediaFactoryWFDPrivate *priv = factory->priv;
230 if (priv->decided_udp_bitrate) {
231 priv->video_bitrate = priv->decide_udp_bitrate[0];
232 priv->min_udp_bitrate = priv->decide_udp_bitrate[1];
233 priv->max_udp_bitrate = priv->decide_udp_bitrate[2];
235 if ((priv->video_width * priv->video_height) >= (1920 * 1080)) {
236 priv->video_bitrate = priv->decide_udp_bitrate[3];
237 priv->min_udp_bitrate = priv->decide_udp_bitrate[4];
238 priv->max_udp_bitrate = priv->decide_udp_bitrate[5];
239 } else if ((priv->video_width * priv->video_height) >= (1280 * 720)) {
240 priv->video_bitrate = priv->decide_udp_bitrate[6];
241 priv->min_udp_bitrate = priv->decide_udp_bitrate[7];
242 priv->max_udp_bitrate = priv->decide_udp_bitrate[8];
243 } else if ((priv->video_width * priv->video_height) >= (960 * 540)) {
244 priv->video_bitrate = priv->decide_udp_bitrate[9];
245 priv->min_udp_bitrate = priv->decide_udp_bitrate[10];
246 priv->max_udp_bitrate = priv->decide_udp_bitrate[11];
247 } else if ((priv->video_width * priv->video_height) >= (854 * 480)) {
248 priv->video_bitrate = priv->decide_udp_bitrate[12];
249 priv->min_udp_bitrate = priv->decide_udp_bitrate[13];
250 priv->max_udp_bitrate = priv->decide_udp_bitrate[14];
251 } else if ((priv->video_width * priv->video_height) >= (640 * 480)) {
252 priv->video_bitrate = priv->decide_udp_bitrate[15];
253 priv->min_udp_bitrate = priv->decide_udp_bitrate[16];
254 priv->max_udp_bitrate = priv->decide_udp_bitrate[17];
260 gst_rtsp_media_factory_wfd_set_venc_bitrate (GstRTSPMediaFactory * factory,
263 GstRTSPMediaFactoryWFD *factory_wfd = GST_RTSP_MEDIA_FACTORY_WFD (factory);
264 GstRTSPMediaFactoryWFDPrivate *priv = factory_wfd->priv;
266 g_object_set (priv->venc, "target-bitrate", bitrate, NULL);
267 priv->video_bitrate = (guint) bitrate;
271 gst_rtsp_media_factory_wfd_get_venc_bitrate (GstRTSPMediaFactory * factory,
276 GstRTSPMediaFactoryWFD *factory_wfd = GST_RTSP_MEDIA_FACTORY_WFD (factory);
277 GstRTSPMediaFactoryWFDPrivate *priv = factory_wfd->priv;
279 g_object_get (priv->venc, "target-bitrate", &cur_bitrate, NULL);
281 if (cur_bitrate == 0) {
282 *bitrate = priv->video_bitrate;
284 *bitrate = (gint) cur_bitrate;
289 gst_rtsp_media_factory_wfd_get_config_bitrate (GstRTSPMediaFactory * factory,
290 guint32 * min, guint32 * max)
292 GstRTSPMediaFactoryWFD *factory_wfd = GST_RTSP_MEDIA_FACTORY_WFD (factory);
293 GstRTSPMediaFactoryWFDPrivate *priv = factory_wfd->priv;
295 *min = priv->min_udp_bitrate;
296 *max = priv->max_udp_bitrate;
300 gst_rtsp_media_factory_wfd_set_config_bitrate (GstRTSPMediaFactoryWFD * factory,
301 guint * config_bitrate)
303 GstRTSPMediaFactoryWFDPrivate *priv = factory->priv;
306 for (idx = 0; idx < 21; idx++) {
307 priv->decide_udp_bitrate[idx] = config_bitrate[idx];
309 priv->decided_udp_bitrate = TRUE;
311 _config_bitrate (factory);
315 gst_rtsp_media_factory_wfd_init (GstRTSPMediaFactoryWFD * factory)
317 GstRTSPMediaFactoryWFDPrivate *priv =
318 GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE (factory);
319 factory->priv = priv;
321 priv->launch = g_strdup (DEFAULT_LAUNCH);
322 priv->shared = DEFAULT_SHARED;
323 priv->protocols = DEFAULT_PROTOCOLS;
324 priv->buffer_size = DEFAULT_BUFFER_SIZE;
326 //priv->videosrc_type = GST_WFD_VSRC_XIMAGESRC;
327 //priv->videosrc_type = GST_WFD_VSRC_XVIMAGESRC;
328 //priv->videosrc_type = GST_WFD_VSRC_CAMERASRC;
329 priv->videosrc_type = GST_WFD_VSRC_VIDEOTESTSRC;
330 priv->video_codec = GST_WFD_VIDEO_H264;
331 priv->video_encoder = g_strdup ("omxh264enc");
332 priv->video_bitrate = 200000;
333 priv->video_width = 640;
334 priv->video_height = 480;
335 priv->video_framerate = 30;
336 priv->video_enc_skip_inbuf_value = 5;
337 priv->min_udp_bitrate = 938861;
338 priv->max_udp_bitrate = 1572864;
339 priv->decided_udp_bitrate = FALSE;
341 priv->audio_device = g_strdup ("alsa_output.1.analog-stereo.monitor");
342 priv->audio_codec = GST_WFD_AUDIO_AAC;
343 priv->audio_encoder_aac = g_strdup ("avenc_aac");
344 priv->audio_encoder_ac3 = g_strdup ("avenc_ac3");
345 priv->audio_latency_time = 10000;
346 priv->audio_buffer_time = 200000;
347 priv->audio_do_timestamp = FALSE;
348 priv->audio_channels = GST_WFD_CHANNEL_2;
349 priv->audio_freq = GST_WFD_FREQ_48000;
351 g_mutex_init (&priv->lock);
355 gst_rtsp_media_factory_wfd_finalize (GObject * obj)
357 GstRTSPMediaFactoryWFD *factory = GST_RTSP_MEDIA_FACTORY_WFD (obj);
358 GstRTSPMediaFactoryWFDPrivate *priv = factory->priv;
360 if (priv->permissions)
361 gst_rtsp_permissions_unref (priv->permissions);
362 g_free (priv->launch);
363 g_mutex_clear (&priv->lock);
365 if (priv->audio_device)
366 g_free (priv->audio_device);
367 if (priv->audio_encoder_aac)
368 g_free (priv->audio_encoder_aac);
369 if (priv->audio_encoder_ac3)
370 g_free (priv->audio_encoder_ac3);
372 if (priv->video_encoder)
373 g_free (priv->video_encoder);
375 G_OBJECT_CLASS (gst_rtsp_media_factory_wfd_parent_class)->finalize (obj);
378 GstRTSPMediaFactoryWFD *
379 gst_rtsp_media_factory_wfd_new (void)
381 GstRTSPMediaFactoryWFD *result;
383 result = g_object_new (GST_TYPE_RTSP_MEDIA_FACTORY_WFD, NULL);
389 gst_rtsp_media_factory_wfd_get_property (GObject * object,
390 guint propid, GValue * value, GParamSpec * pspec)
392 //GstRTSPMediaFactoryWFD *factory = GST_RTSP_MEDIA_FACTORY_WFD (object);
396 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
401 gst_rtsp_media_factory_wfd_set_property (GObject * object,
402 guint propid, const GValue * value, GParamSpec * pspec)
404 //GstRTSPMediaFactoryWFD *factory = GST_RTSP_MEDIA_FACTORY_WFD (object);
408 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
412 static GstPadProbeReturn
413 rtsp_media_wfd_dump_data (GstPad * pad, GstPadProbeInfo * info, gpointer u_data)
420 if (info->type == (GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_PUSH)) {
421 GstBuffer *buffer = gst_pad_probe_info_get_buffer (info);
423 gst_buffer_map (buffer, &mapinfo, GST_MAP_READ);
425 size = gst_buffer_get_size (buffer);
427 f = fopen ("/root/probe.ts", "a");
429 fwrite (data, size, 1, f);
432 gst_buffer_unmap (buffer, &mapinfo);
435 return GST_PAD_PROBE_OK;
439 _rtsp_media_factory_wfd_create_audio_capture_bin (GstRTSPMediaFactoryWFD *
440 factory, GstBin * srcbin)
442 GstElement *audiosrc = NULL;
443 GstElement *acaps = NULL;
444 GstElement *acaps2 = NULL;
445 GstElement *aenc = NULL;
446 GstElement *audio_convert = NULL;
447 GstElement *aqueue = NULL;
448 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
449 GstStructure *audio_properties_name = NULL;
452 gboolean is_enc_req = TRUE;
454 gchar *acodec = NULL;
456 priv = factory->priv;
458 /* create audio src element */
459 audiosrc = gst_element_factory_make ("pulsesrc", "audiosrc");
461 GST_ERROR_OBJECT (factory, "failed to create audiosrc element");
465 GST_INFO_OBJECT (factory, "audio device : %s", priv->audio_device);
466 GST_INFO_OBJECT (factory, "audio latency time : %"G_GUINT64_FORMAT,
467 priv->audio_latency_time);
468 GST_INFO_OBJECT (factory, "audio_buffer_time : %"G_GUINT64_FORMAT,
469 priv->audio_buffer_time);
470 GST_INFO_OBJECT (factory, "audio_do_timestamp : %d",
471 priv->audio_do_timestamp);
473 audio_properties_name = gst_structure_new_from_string (priv->audio_device);
475 g_object_set (audiosrc, "stream-properties", audio_properties_name, NULL);
476 g_object_set (audiosrc, "buffer-time", (gint64) priv->audio_buffer_time,
478 g_object_set (audiosrc, "latency-time", (gint64) priv->audio_latency_time,
480 g_object_set (audiosrc, "do-timestamp", (gboolean) priv->audio_do_timestamp,
482 g_object_set (audiosrc, "provide-clock", (gboolean) FALSE, NULL);
483 g_object_set (audiosrc, "is-live", (gboolean) TRUE, NULL);
485 if (priv->audio_codec == GST_WFD_AUDIO_LPCM) {
486 /* To meet miracast certification */
487 gint64 block_size = 1920;
488 g_object_set (audiosrc, "blocksize", (gint64) block_size, NULL);
490 audio_convert = gst_element_factory_make ("capssetter", "audio_convert");
491 if (NULL == audio_convert) {
492 GST_ERROR_OBJECT (factory, "failed to create audio convert element");
495 g_object_set (audio_convert, "caps", gst_caps_new_simple ("audio/x-lpcm",
496 "width", G_TYPE_INT, 16,
497 "rate", G_TYPE_INT, 48000,
498 "channels", G_TYPE_INT, 2,
499 "dynamic_range", G_TYPE_INT, 0,
500 "emphasis", G_TYPE_BOOLEAN, FALSE,
501 "mute", G_TYPE_BOOLEAN, FALSE, NULL), NULL);
502 g_object_set (audio_convert, "join", (gboolean) FALSE, NULL);
503 g_object_set (audio_convert, "replace", (gboolean) TRUE, NULL);
505 acaps2 = gst_element_factory_make ("capsfilter", "audiocaps2");
506 if (NULL == acaps2) {
507 GST_ERROR_OBJECT (factory, "failed to create audio capsilfter element");
510 /* In case of LPCM, uses big endian */
511 g_object_set (G_OBJECT (acaps2), "caps",
512 gst_caps_new_simple ("audio/x-raw", "format", G_TYPE_STRING, "S16BE",
513 /* In case of LPCM, uses big endian */
514 "rate", G_TYPE_INT, 48000,
515 "channels", G_TYPE_INT, 2, NULL), NULL);
518 /* create audio caps element */
519 acaps = gst_element_factory_make ("capsfilter", "audiocaps");
521 GST_ERROR_OBJECT (factory, "failed to create audio capsilfter element");
525 if (priv->audio_channels == GST_WFD_CHANNEL_2)
527 else if (priv->audio_channels == GST_WFD_CHANNEL_4)
529 else if (priv->audio_channels == GST_WFD_CHANNEL_6)
531 else if (priv->audio_channels == GST_WFD_CHANNEL_8)
536 if (priv->audio_freq == GST_WFD_FREQ_44100)
538 else if (priv->audio_freq == GST_WFD_FREQ_48000)
543 if (priv->audio_codec == GST_WFD_AUDIO_LPCM) {
544 g_object_set (G_OBJECT (acaps), "caps",
545 gst_caps_new_simple ("audio/x-lpcm", "width", G_TYPE_INT, 16,
546 "rate", G_TYPE_INT, 48000,
547 "channels", G_TYPE_INT, 2,
548 "dynamic_range", G_TYPE_INT, 0,
549 "emphasis", G_TYPE_BOOLEAN, FALSE,
550 "mute", G_TYPE_BOOLEAN, FALSE, NULL), NULL);
551 } else if ((priv->audio_codec == GST_WFD_AUDIO_AAC)
552 || (priv->audio_codec == GST_WFD_AUDIO_AC3)) {
553 g_object_set (G_OBJECT (acaps), "caps", gst_caps_new_simple ("audio/x-raw",
554 "endianness", G_TYPE_INT, 1234, "signed", G_TYPE_BOOLEAN, TRUE,
555 "depth", G_TYPE_INT, 16, "rate", G_TYPE_INT, freq, "channels",
556 G_TYPE_INT, channels, NULL), NULL);
559 if (priv->audio_codec == GST_WFD_AUDIO_AAC) {
560 acodec = g_strdup (priv->audio_encoder_aac);
562 } else if (priv->audio_codec == GST_WFD_AUDIO_AC3) {
563 acodec = g_strdup (priv->audio_encoder_ac3);
565 } else if (priv->audio_codec == GST_WFD_AUDIO_LPCM) {
566 GST_DEBUG_OBJECT (factory, "No codec required, raw data will be sent");
569 GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
574 aenc = gst_element_factory_make (acodec, "audioenc");
576 GST_ERROR_OBJECT (factory, "failed to create audio encoder element");
580 g_object_set (aenc, "compliance", -2, NULL);
581 g_object_set (aenc, "tolerance", 400000000, NULL);
582 g_object_set (aenc, "bitrate", (guint) 128000, NULL);
583 g_object_set (aenc, "rate-control", 2, NULL);
585 aqueue = gst_element_factory_make ("queue", "audio-queue");
587 GST_ERROR_OBJECT (factory, "failed to create audio queue element");
591 gst_bin_add_many (srcbin, audiosrc, acaps, aenc, aqueue, NULL);
593 if (!gst_element_link_many (audiosrc, acaps, aenc, aqueue, NULL)) {
594 GST_ERROR_OBJECT (factory, "Failed to link audio src elements...");
598 aqueue = gst_element_factory_make ("queue", "audio-queue");
600 GST_ERROR_OBJECT (factory, "failed to create audio queue element");
604 gst_bin_add_many (srcbin, audiosrc, acaps2, audio_convert, acaps, aqueue,
607 if (!gst_element_link_many (audiosrc, acaps2, audio_convert, acaps, aqueue,
609 GST_ERROR_OBJECT (factory, "Failed to link audio src elements...");
614 priv->audio_queue = aqueue;
617 if (audio_properties_name)
618 gst_structure_free (audio_properties_name);
624 if (audio_properties_name)
625 gst_structure_free (audio_properties_name);
630 _rtsp_media_factory_wfd_create_videotest_bin (GstRTSPMediaFactoryWFD * factory,
633 GstElement *videosrc = NULL;
634 GstElement *vcaps = NULL;
635 GstElement *videoconvert = NULL;
636 GstElement *venc_caps = NULL;
637 gchar *vcodec = NULL;
638 GstElement *venc = NULL;
639 GstElement *vparse = NULL;
640 GstElement *vqueue = NULL;
641 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
643 priv = factory->priv;
645 GST_INFO_OBJECT (factory, "picked videotestsrc as video source");
647 videosrc = gst_element_factory_make ("videotestsrc", "videosrc");
648 if (NULL == videosrc) {
649 GST_ERROR_OBJECT (factory, "failed to create ximagesrc element");
653 /* create video caps element */
654 vcaps = gst_element_factory_make ("capsfilter", "videocaps");
656 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
660 g_object_set (G_OBJECT (vcaps), "caps",
661 gst_caps_new_simple ("video/x-raw",
662 "format", G_TYPE_STRING, "I420",
663 "width", G_TYPE_INT, priv->video_width,
664 "height", G_TYPE_INT, priv->video_height,
665 "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
668 /* create video convert element */
669 videoconvert = gst_element_factory_make ("videoconvert", "videoconvert");
670 if (NULL == videoconvert) {
671 GST_ERROR_OBJECT (factory, "failed to create video videoconvert element");
675 venc_caps = gst_element_factory_make ("capsfilter", "venc_caps");
676 if (NULL == venc_caps) {
677 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
681 g_object_set (G_OBJECT (venc_caps), "caps",
682 gst_caps_new_simple ("video/x-raw",
683 "format", G_TYPE_STRING, "SN12",
684 "width", G_TYPE_INT, priv->video_width,
685 "height", G_TYPE_INT, priv->video_height,
686 "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
689 if (priv->video_codec == GST_WFD_VIDEO_H264)
690 vcodec = g_strdup (priv->video_encoder);
692 GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
696 venc = gst_element_factory_make (vcodec, "videoenc");
701 GST_ERROR_OBJECT (factory, "failed to create video encoder element");
705 g_object_set (venc, "aud", 0, NULL);
706 g_object_set (venc, "byte-stream", 1, NULL);
707 g_object_set (venc, "bitrate", 512, NULL);
709 vparse = gst_element_factory_make ("h264parse", "videoparse");
710 if (NULL == vparse) {
711 GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
714 g_object_set (vparse, "config-interval", 1, NULL);
716 vqueue = gst_element_factory_make ("queue", "video-queue");
718 GST_ERROR_OBJECT (factory, "failed to create video queue element");
722 gst_bin_add_many (srcbin, videosrc, vcaps, videoconvert, venc_caps, venc,
723 vparse, vqueue, NULL);
724 if (!gst_element_link_many (videosrc, vcaps, videoconvert, venc_caps, venc,
725 vparse, vqueue, NULL)) {
726 GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
730 priv->video_queue = vqueue;
740 _rtsp_media_factory_wfd_create_waylandsrc_bin (GstRTSPMediaFactoryWFD * factory,
743 GstElement *videosrc = NULL;
744 GstElement *vcaps = NULL;
745 gchar *vcodec = NULL;
746 GstElement *venc = NULL;
747 GstElement *vparse = NULL;
748 GstElement *vqueue = NULL;
749 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
751 priv = factory->priv;
753 GST_INFO_OBJECT (factory, "picked waylandsrc as video source");
755 videosrc = gst_element_factory_make ("waylandsrc", "videosrc");
756 if (NULL == videosrc) {
757 GST_ERROR_OBJECT (factory, "failed to create ximagesrc element");
761 /* create video caps element */
762 vcaps = gst_element_factory_make ("capsfilter", "videocaps");
764 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
768 g_object_set (G_OBJECT (vcaps), "caps",
769 gst_caps_new_simple ("video/x-raw",
770 "format", G_TYPE_STRING, "SN12",
771 "width", G_TYPE_INT, priv->video_width,
772 "height", G_TYPE_INT, priv->video_height,
773 "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
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);
795 g_object_set (venc, "target-bitrate", priv->video_bitrate, NULL);
797 vparse = gst_element_factory_make ("h264parse", "videoparse");
798 if (NULL == vparse) {
799 GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
802 g_object_set (vparse, "config-interval", 1, NULL);
804 vqueue = gst_element_factory_make ("queue", "video-queue");
806 GST_ERROR_OBJECT (factory, "failed to create video queue element");
810 gst_bin_add_many (srcbin, videosrc, vcaps, venc, vparse, vqueue, NULL);
811 if (!gst_element_link_many (videosrc, vcaps, venc, vparse, vqueue, NULL)) {
812 GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
816 priv->video_queue = vqueue;
826 _rtsp_media_factory_wfd_create_camera_capture_bin (GstRTSPMediaFactoryWFD *
827 factory, GstBin * srcbin)
829 GstElement *videosrc = NULL;
830 GstElement *vcaps = NULL;
831 GstElement *venc = NULL;
832 GstElement *vparse = NULL;
833 GstElement *vqueue = NULL;
834 gchar *vcodec = NULL;
835 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
837 priv = factory->priv;
839 videosrc = gst_element_factory_make ("camerasrc", "videosrc");
840 if (NULL == videosrc) {
841 GST_ERROR_OBJECT (factory, "failed to create camerasrc element");
845 /* create video caps element */
846 vcaps = gst_element_factory_make ("capsfilter", "videocaps");
848 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
852 GST_INFO_OBJECT (factory, "picked camerasrc as video source");
853 g_object_set (G_OBJECT (vcaps), "caps",
854 gst_caps_new_simple ("video/x-raw",
855 "width", G_TYPE_INT, priv->video_width,
856 "height", G_TYPE_INT, priv->video_height,
857 "format", G_TYPE_STRING, "SN12",
858 "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
861 if (priv->video_codec == GST_WFD_VIDEO_H264)
862 vcodec = g_strdup (priv->video_encoder);
864 GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
868 venc = gst_element_factory_make (vcodec, "videoenc");
873 GST_ERROR_OBJECT (factory, "failed to create video encoder element");
877 g_object_set (venc, "bitrate", priv->video_bitrate, NULL);
878 g_object_set (venc, "byte-stream", 1, NULL);
879 g_object_set (venc, "append-dci", 1, NULL);
881 vparse = gst_element_factory_make ("h264parse", "videoparse");
882 if (NULL == vparse) {
883 GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
886 g_object_set (vparse, "config-interval", 1, NULL);
888 vqueue = gst_element_factory_make ("queue", "video-queue");
890 GST_ERROR_OBJECT (factory, "failed to create video queue element");
894 gst_bin_add_many (srcbin, videosrc, vcaps, venc, vparse, vqueue, NULL);
896 if (!gst_element_link_many (videosrc, vcaps, venc, vparse, vqueue, NULL)) {
897 GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
901 priv->video_queue = vqueue;
911 _rtsp_media_factory_wfd_create_xcapture_bin (GstRTSPMediaFactoryWFD * factory,
914 GstElement *videosrc = NULL;
915 GstElement *vcaps = NULL;
916 GstElement *venc_caps = NULL;
917 GstElement *videoconvert = NULL, *videoscale = NULL;
918 gchar *vcodec = NULL;
919 GstElement *venc = NULL;
920 GstElement *vparse = NULL;
921 GstElement *vqueue = NULL;
922 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
924 priv = factory->priv;
926 GST_INFO_OBJECT (factory, "picked ximagesrc as video source");
928 videosrc = gst_element_factory_make ("ximagesrc", "videosrc");
929 if (NULL == videosrc) {
930 GST_ERROR_OBJECT (factory, "failed to create ximagesrc element");
934 videoscale = gst_element_factory_make ("videoscale", "videoscale");
935 if (NULL == videoscale) {
936 GST_ERROR_OBJECT (factory, "failed to create videoscale element");
940 videoconvert = gst_element_factory_make ("videoconvert", "videoconvert");
941 if (NULL == videoconvert) {
942 GST_ERROR_OBJECT (factory, "failed to create videoconvert element");
946 /* create video caps element */
947 vcaps = gst_element_factory_make ("capsfilter", "videocaps");
949 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
953 g_object_set (G_OBJECT (vcaps), "caps",
954 gst_caps_new_simple ("video/x-raw",
955 "width", G_TYPE_INT, priv->video_width,
956 "height", G_TYPE_INT, priv->video_height,
957 "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
960 if (priv->video_codec == GST_WFD_VIDEO_H264)
961 vcodec = g_strdup (priv->video_encoder);
963 GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
967 venc = gst_element_factory_make (vcodec, "videoenc");
972 GST_ERROR_OBJECT (factory, "failed to create video encoder element");
976 g_object_set (venc, "aud", 0, NULL);
977 g_object_set (venc, "byte-stream", 1, NULL);
978 g_object_set (venc, "bitrate", 512, NULL);
980 venc_caps = gst_element_factory_make ("capsfilter", "venc_caps");
981 if (NULL == venc_caps) {
982 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
986 g_object_set (G_OBJECT (venc_caps), "caps",
987 gst_caps_new_simple ("video/x-h264",
988 "profile", G_TYPE_STRING, "baseline", NULL), NULL);
990 vparse = gst_element_factory_make ("h264parse", "videoparse");
991 if (NULL == vparse) {
992 GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
995 g_object_set (vparse, "config-interval", 1, NULL);
997 vqueue = gst_element_factory_make ("queue", "video-queue");
999 GST_ERROR_OBJECT (factory, "failed to create video queue element");
1003 gst_bin_add_many (srcbin, videosrc, videoscale, videoconvert, vcaps, venc,
1004 venc_caps, vparse, vqueue, NULL);
1005 if (!gst_element_link_many (videosrc, videoscale, videoconvert, vcaps, venc,
1006 venc_caps, vparse, vqueue, NULL)) {
1007 GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
1011 priv->video_queue = vqueue;
1021 _rtsp_media_factory_wfd_create_xvcapture_bin (GstRTSPMediaFactoryWFD * factory,
1024 GstElement *videosrc = NULL;
1025 GstElement *vcaps = NULL;
1026 gchar *vcodec = NULL;
1027 GstElement *venc = NULL;
1028 GstElement *vparse = NULL;
1029 GstElement *vqueue = NULL;
1030 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1032 priv = factory->priv;
1034 GST_INFO_OBJECT (factory, "picked xvimagesrc as video source");
1036 videosrc = gst_element_factory_make ("xvimagesrc", "videosrc");
1037 if (NULL == videosrc) {
1038 GST_ERROR_OBJECT (factory, "failed to create xvimagesrc element");
1042 /* create video caps element */
1043 vcaps = gst_element_factory_make ("capsfilter", "videocaps");
1044 if (NULL == vcaps) {
1045 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
1049 g_object_set (G_OBJECT (vcaps), "caps",
1050 gst_caps_new_simple ("video/x-raw",
1051 "width", G_TYPE_INT, priv->video_width,
1052 "height", G_TYPE_INT, priv->video_height,
1053 "format", G_TYPE_STRING, "SN12",
1054 "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
1057 if (priv->video_codec == GST_WFD_VIDEO_H264) {
1058 vcodec = g_strdup (priv->video_encoder);
1060 GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
1064 venc = gst_element_factory_make (vcodec, "videoenc");
1066 GST_ERROR_OBJECT (factory, "failed to create video encoder element");
1069 g_object_set (venc, "bitrate", priv->video_bitrate, NULL);
1070 g_object_set (venc, "byte-stream", 1, NULL);
1071 g_object_set (venc, "append-dci", 1, NULL);
1072 g_object_set (venc, "idr-period", 120, NULL);
1073 g_object_set (venc, "skip-inbuf", priv->video_enc_skip_inbuf_value, NULL);
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 (srcbin, videosrc, vcaps, venc, vparse, vqueue, NULL);
1089 if (!gst_element_link_many (videosrc, vcaps, venc, vparse, vqueue, NULL)) {
1090 GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
1094 priv->video_queue = vqueue;
1108 _rtsp_media_factory_wfd_create_srcbin (GstRTSPMediaFactoryWFD * factory)
1110 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
1112 GstBin *srcbin = NULL;
1113 GstElement *mux = NULL;
1114 GstElement *mux_queue = NULL;
1115 GstElement *payload = NULL;
1116 GstPad *srcpad = NULL;
1117 GstPad *mux_vsinkpad = NULL;
1118 GstPad *mux_asinkpad = NULL;
1120 priv = factory->priv;
1122 /* create source bin */
1123 srcbin = GST_BIN (gst_bin_new ("srcbin"));
1125 GST_ERROR_OBJECT (factory, "failed to create source bin...");
1129 /* create video src element */
1130 switch (priv->videosrc_type) {
1131 case GST_WFD_VSRC_XIMAGESRC:
1132 if (!_rtsp_media_factory_wfd_create_xcapture_bin (factory, srcbin)) {
1133 GST_ERROR_OBJECT (factory, "failed to create xcapture bin...");
1137 case GST_WFD_VSRC_XVIMAGESRC:
1138 if (!_rtsp_media_factory_wfd_create_xvcapture_bin (factory, srcbin)) {
1139 GST_ERROR_OBJECT (factory, "failed to create xvcapture bin...");
1143 case GST_WFD_VSRC_CAMERASRC:
1144 if (!_rtsp_media_factory_wfd_create_camera_capture_bin (factory, srcbin)) {
1145 GST_ERROR_OBJECT (factory, "failed to create camera capture bin...");
1149 case GST_WFD_VSRC_VIDEOTESTSRC:
1150 if (!_rtsp_media_factory_wfd_create_videotest_bin (factory, srcbin)) {
1151 GST_ERROR_OBJECT (factory, "failed to create videotestsrc bin...");
1155 case GST_WFD_VSRC_WAYLANDSRC:
1156 if (!_rtsp_media_factory_wfd_create_waylandsrc_bin (factory, srcbin)) {
1157 GST_ERROR_OBJECT (factory, "failed to create videotestsrc bin...");
1162 GST_ERROR_OBJECT (factory, "unknow mode selected...");
1166 mux = gst_element_factory_make ("mpegtsmux", "tsmux");
1168 GST_ERROR_OBJECT (factory, "failed to create muxer element");
1172 g_object_set (mux, "wfd-mode", TRUE, NULL);
1174 mux_queue = gst_element_factory_make ("queue", "muxer-queue");
1176 GST_ERROR_OBJECT (factory, "failed to create muxer-queue element");
1180 g_object_set (mux_queue, "max-size-buffers", 20000, NULL);
1182 payload = gst_element_factory_make ("rtpmp2tpay", "pay0");
1184 GST_ERROR_OBJECT (factory, "failed to create payload element");
1188 g_object_set (payload, "pt", 33, NULL);
1189 g_object_set (payload, "mtu", priv->mtu_size, NULL);
1190 g_object_set (payload, "rtp-flush", (gboolean) TRUE, NULL);
1192 gst_bin_add_many (srcbin, mux, mux_queue, payload, NULL);
1194 if (!gst_element_link_many (mux, mux_queue, payload, NULL)) {
1195 GST_ERROR_OBJECT (factory, "Failed to link muxer & payload...");
1199 /* request video sink pad from muxer, which has elementary pid 0x1011 */
1200 mux_vsinkpad = gst_element_get_request_pad (mux, "sink_4113");
1201 if (!mux_vsinkpad) {
1202 GST_ERROR_OBJECT (factory, "Failed to get sink pad from muxer...");
1206 /* request srcpad from video queue */
1207 srcpad = gst_element_get_static_pad (priv->video_queue, "src");
1209 GST_ERROR_OBJECT (factory, "Failed to get srcpad from video queue...");
1213 if (gst_pad_link (srcpad, mux_vsinkpad) != GST_PAD_LINK_OK) {
1214 GST_ERROR_OBJECT (factory,
1215 "Failed to link video queue src pad & muxer video sink pad...");
1219 gst_object_unref (mux_vsinkpad);
1220 gst_object_unref (srcpad);
1223 /* create audio source elements & add to pipeline */
1224 if (!_rtsp_media_factory_wfd_create_audio_capture_bin (factory, srcbin))
1227 /* request audio sink pad from muxer, which has elementary pid 0x1100 */
1228 mux_asinkpad = gst_element_get_request_pad (mux, "sink_4352");
1229 if (!mux_asinkpad) {
1230 GST_ERROR_OBJECT (factory, "Failed to get sinkpad from muxer...");
1234 /* request srcpad from audio queue */
1235 srcpad = gst_element_get_static_pad (priv->audio_queue, "src");
1237 GST_ERROR_OBJECT (factory, "Failed to get srcpad from audio queue...");
1241 /* link audio queue's srcpad & muxer sink pad */
1242 if (gst_pad_link (srcpad, mux_asinkpad) != GST_PAD_LINK_OK) {
1243 GST_ERROR_OBJECT (factory,
1244 "Failed to link audio queue src pad & muxer audio sink pad...");
1247 gst_object_unref (mux_asinkpad);
1248 gst_object_unref (srcpad);
1252 GstPad *pad_probe = NULL;
1253 pad_probe = gst_element_get_static_pad (mux, "src");
1255 if (NULL == pad_probe) {
1256 GST_INFO_OBJECT (factory, "pad for probe not created");
1258 GST_INFO_OBJECT (factory, "pad for probe SUCCESSFUL");
1260 gst_pad_add_probe (pad_probe, GST_PAD_PROBE_TYPE_BUFFER,
1261 rtsp_media_wfd_dump_data, factory, NULL);
1264 GST_DEBUG_OBJECT (factory, "successfully created source bin...");
1266 return GST_ELEMENT_CAST (srcbin);
1269 GST_ERROR_OBJECT (factory, "Failed to create pipeline");
1274 rtsp_media_factory_wfd_create_element (GstRTSPMediaFactory * factory,
1275 const GstRTSPUrl * url)
1277 GstRTSPMediaFactoryWFD *_factory = GST_RTSP_MEDIA_FACTORY_WFD_CAST (factory);
1278 GstElement *element = NULL;
1280 GST_RTSP_MEDIA_FACTORY_WFD_LOCK (factory);
1282 element = _rtsp_media_factory_wfd_create_srcbin (_factory);
1284 GST_RTSP_MEDIA_FACTORY_WFD_UNLOCK (factory);
1289 static GstRTSPMedia *
1290 rtsp_media_factory_wfd_construct (GstRTSPMediaFactory * factory,
1291 const GstRTSPUrl * url)
1293 GstRTSPMedia *media;
1294 GstElement *element, *pipeline;
1295 GstRTSPMediaFactoryClass *klass;
1297 klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
1299 if (!klass->create_pipeline)
1302 element = gst_rtsp_media_factory_create_element (factory, url);
1303 if (element == NULL)
1306 /* create a new empty media */
1307 //media = gst_rtsp_media_new (element);
1308 media = g_object_new (GST_TYPE_RTSP_MEDIA_EXT, "element", element, NULL);
1310 gst_rtsp_media_collect_streams (media);
1312 pipeline = klass->create_pipeline (factory, media);
1313 if (pipeline == NULL)
1321 g_critical ("no create_pipeline function");
1326 g_critical ("could not create element");
1331 g_critical ("can't create pipeline");
1332 g_object_unref (media);