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"
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;
66 guint video_framerate;
67 guint video_enc_skip_inbuf_value;
68 GstElement *video_queue;
71 gchar *audio_encoder_aac;
72 gchar *audio_encoder_ac3;
74 guint64 audio_latency_time;
75 guint64 audio_buffer_time;
76 gboolean audio_do_timestamp;
77 guint8 audio_channels;
80 GstElement *audio_queue;
82 guint64 video_resolution_supported;
87 #define DEFAULT_LAUNCH NULL
88 #define DEFAULT_SHARED FALSE
89 #define DEFAULT_PROTOCOLS GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_UDP_MCAST | \
90 GST_RTSP_LOWER_TRANS_TCP
91 #define DEFAULT_BUFFER_SIZE 0x80000
107 SIGNAL_MEDIA_CONSTRUCTED,
108 SIGNAL_MEDIA_CONFIGURE,
112 GST_DEBUG_CATEGORY_STATIC (rtsp_media_wfd_debug);
113 #define GST_CAT_DEFAULT rtsp_media_wfd_debug
115 static void gst_rtsp_media_factory_wfd_get_property (GObject * object,
116 guint propid, GValue * value, GParamSpec * pspec);
117 static void gst_rtsp_media_factory_wfd_set_property (GObject * object,
118 guint propid, const GValue * value, GParamSpec * pspec);
120 static void gst_rtsp_media_factory_wfd_finalize (GObject * obj);
123 static GstElement *rtsp_media_factory_wfd_create_element (GstRTSPMediaFactory *
124 factory, const GstRTSPUrl * url);
125 static GstRTSPMedia *rtsp_media_factory_wfd_construct (GstRTSPMediaFactory *
126 factory, const GstRTSPUrl * url);
128 G_DEFINE_TYPE (GstRTSPMediaFactoryWFD, gst_rtsp_media_factory_wfd,
129 GST_TYPE_RTSP_MEDIA_FACTORY);
132 gst_rtsp_media_factory_wfd_class_init (GstRTSPMediaFactoryWFDClass * klass)
134 GObjectClass *gobject_class;
135 GstRTSPMediaFactoryClass *factory_class;
137 g_type_class_add_private (klass, sizeof (GstRTSPMediaFactoryWFDPrivate));
139 gobject_class = G_OBJECT_CLASS (klass);
140 factory_class = GST_RTSP_MEDIA_FACTORY_CLASS (klass);
142 gobject_class->get_property = gst_rtsp_media_factory_wfd_get_property;
143 gobject_class->set_property = gst_rtsp_media_factory_wfd_set_property;
144 gobject_class->finalize = gst_rtsp_media_factory_wfd_finalize;
146 factory_class->construct = rtsp_media_factory_wfd_construct;
147 factory_class->create_element = rtsp_media_factory_wfd_create_element;
149 GST_DEBUG_CATEGORY_INIT (rtsp_media_wfd_debug, "rtspmediafactorywfd", 0,
150 "GstRTSPMediaFactoryWFD");
153 void gst_rtsp_media_factory_wfd_set (GstRTSPMediaFactoryWFD * factory,
154 guint8 videosrc_type, gchar *audio_device, guint64 audio_latency_time,
155 guint64 audio_buffer_time, gboolean audio_do_timestamp, guint mtu_size)
157 GstRTSPMediaFactoryWFDPrivate *priv =
158 GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE (factory);
159 factory->priv = priv;
161 priv->videosrc_type = videosrc_type;
162 priv->audio_device = audio_device;
163 priv->audio_latency_time = audio_latency_time;
164 priv->audio_buffer_time = audio_buffer_time;
165 priv->audio_do_timestamp = audio_do_timestamp;
166 priv->mtu_size = mtu_size;
169 void gst_rtsp_media_factory_wfd_set_encoders (GstRTSPMediaFactoryWFD * factory,
170 gchar *video_encoder, gchar *audio_encoder_aac, gchar *audio_encoder_ac3)
172 GstRTSPMediaFactoryWFDPrivate *priv =
173 GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE (factory);
174 factory->priv = priv;
176 priv->video_encoder = video_encoder;
177 priv->audio_encoder_aac = audio_encoder_aac;
178 priv->audio_encoder_ac3 = audio_encoder_ac3;
181 void gst_rtsp_media_factory_wfd_set_dump_ts (GstRTSPMediaFactoryWFD * factory,
184 GstRTSPMediaFactoryWFDPrivate *priv =
185 GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE (factory);
186 factory->priv = priv;
188 priv->dump_ts = dump_ts;
190 void gst_rtsp_media_factory_wfd_set_negotiated_resolution (GstRTSPMediaFactory *factory,
191 guint32 width, guint32 height)
193 GstRTSPMediaFactoryWFD *factory_wfd = GST_RTSP_MEDIA_FACTORY_WFD (factory);
194 GstRTSPMediaFactoryWFDPrivate *priv = factory_wfd->priv;
196 priv->video_width = width;
197 priv->video_height = height;
199 void gst_rtsp_media_factory_wfd_set_audio_codec (GstRTSPMediaFactory *factory,
202 GstRTSPMediaFactoryWFD *factory_wfd = GST_RTSP_MEDIA_FACTORY_WFD (factory);
203 GstRTSPMediaFactoryWFDPrivate *priv = factory_wfd->priv;
205 priv->audio_codec = audio_codec;
209 gst_rtsp_media_factory_wfd_init (GstRTSPMediaFactoryWFD * factory)
211 GstRTSPMediaFactoryWFDPrivate *priv =
212 GST_RTSP_MEDIA_FACTORY_WFD_GET_PRIVATE (factory);
213 factory->priv = priv;
215 priv->launch = g_strdup (DEFAULT_LAUNCH);
216 priv->shared = DEFAULT_SHARED;
217 priv->protocols = DEFAULT_PROTOCOLS;
218 priv->buffer_size = DEFAULT_BUFFER_SIZE;
220 //priv->videosrc_type = GST_WFD_VSRC_XIMAGESRC;
221 //priv->videosrc_type = GST_WFD_VSRC_XVIMAGESRC;
222 //priv->videosrc_type = GST_WFD_VSRC_CAMERASRC;
223 priv->videosrc_type = GST_WFD_VSRC_VIDEOTESTSRC;
224 priv->video_codec = GST_WFD_VIDEO_H264;
225 priv->video_encoder = g_strdup ("omxh264enc");
226 priv->video_bitrate = 200000;
227 priv->video_width = 640;
228 priv->video_height = 480;
229 priv->video_framerate = 30;
230 priv->video_enc_skip_inbuf_value = 5;
232 priv->audio_device = g_strdup ("alsa_output.1.analog-stereo.monitor");
233 priv->audio_codec = GST_WFD_AUDIO_AAC;
234 priv->audio_encoder_aac = g_strdup ("avenc_aac");
235 priv->audio_encoder_ac3 = g_strdup ("avenc_ac3");
236 priv->audio_latency_time = 10000;
237 priv->audio_buffer_time = 200000;
238 priv->audio_do_timestamp = FALSE;
239 priv->audio_channels = GST_WFD_CHANNEL_2;
240 priv->audio_freq = GST_WFD_FREQ_48000;
242 g_mutex_init (&priv->lock);
246 gst_rtsp_media_factory_wfd_finalize (GObject * obj)
248 GstRTSPMediaFactoryWFD *factory = GST_RTSP_MEDIA_FACTORY_WFD (obj);
249 GstRTSPMediaFactoryWFDPrivate *priv = factory->priv;
251 if (priv->permissions)
252 gst_rtsp_permissions_unref (priv->permissions);
253 g_free (priv->launch);
254 g_mutex_clear (&priv->lock);
256 if (priv->audio_device)
257 g_free (priv->audio_device);
258 if (priv->audio_encoder_aac)
259 g_free (priv->audio_encoder_aac);
260 if (priv->audio_encoder_ac3)
261 g_free (priv->audio_encoder_ac3);
263 if (priv->video_encoder)
264 g_free (priv->video_encoder);
266 G_OBJECT_CLASS (gst_rtsp_media_factory_wfd_parent_class)->finalize (obj);
269 GstRTSPMediaFactoryWFD *
270 gst_rtsp_media_factory_wfd_new (void)
272 GstRTSPMediaFactoryWFD *result;
274 result = g_object_new (GST_TYPE_RTSP_MEDIA_FACTORY_WFD, NULL);
280 gst_rtsp_media_factory_wfd_get_property (GObject * object,
281 guint propid, GValue * value, GParamSpec * pspec)
283 //GstRTSPMediaFactoryWFD *factory = GST_RTSP_MEDIA_FACTORY_WFD (object);
287 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
292 gst_rtsp_media_factory_wfd_set_property (GObject * object,
293 guint propid, const GValue * value, GParamSpec * pspec)
295 //GstRTSPMediaFactoryWFD *factory = GST_RTSP_MEDIA_FACTORY_WFD (object);
299 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
303 static GstPadProbeReturn
304 rtsp_media_wfd_dump_data (GstPad * pad, GstPadProbeInfo *info, gpointer u_data)
311 if (info->type == (GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_PUSH)) {
312 GstBuffer *buffer = gst_pad_probe_info_get_buffer (info);
314 gst_buffer_map (buffer, &mapinfo, GST_MAP_READ);
316 size = gst_buffer_get_size (buffer);
318 f = fopen ("/root/probe.ts", "a");
320 fwrite (data, size, 1, f);
323 gst_buffer_unmap (buffer, &mapinfo);
326 return GST_PAD_PROBE_OK;
330 _rtsp_media_factory_wfd_create_audio_capture_bin (GstRTSPMediaFactoryWFD *
331 factory, GstBin * srcbin)
333 GstElement *audiosrc = NULL;
334 GstElement *acaps = NULL;
335 GstElement *acaps2 = NULL;
336 GstElement *aenc = NULL;
337 GstElement *audio_convert = NULL;
338 GstElement *aqueue = NULL;
339 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
340 GstStructure *audio_properties_name = NULL;
343 gboolean is_enc_req = TRUE;
345 gchar *acodec = NULL;
347 priv = factory->priv;
349 /* create audio src element */
350 audiosrc = gst_element_factory_make ("pulsesrc", "audiosrc");
352 GST_ERROR_OBJECT (factory, "failed to create audiosrc element");
356 GST_INFO_OBJECT (factory, "audio device : %s", priv->audio_device);
357 GST_INFO_OBJECT (factory, "audio latency time : %"G_GUINT64_FORMAT,
358 priv->audio_latency_time);
359 GST_INFO_OBJECT (factory, "audio_buffer_time : %"G_GUINT64_FORMAT,
360 priv->audio_buffer_time);
361 GST_INFO_OBJECT (factory, "audio_do_timestamp : %d",
362 priv->audio_do_timestamp);
364 audio_properties_name = gst_structure_new_from_string(priv->audio_device);
366 g_object_set (audiosrc, "stream-properties", audio_properties_name, NULL);
367 g_object_set (audiosrc, "buffer-time", (gint64) priv->audio_buffer_time,
369 g_object_set (audiosrc, "latency-time", (gint64) priv->audio_latency_time,
371 g_object_set (audiosrc, "do-timestamp", (gboolean) priv->audio_do_timestamp,
373 g_object_set (audiosrc, "provide-clock", (gboolean) FALSE, NULL);
374 g_object_set (audiosrc, "is-live", (gboolean) TRUE, NULL);
376 if (priv->audio_codec == GST_WFD_AUDIO_LPCM) {
377 /* To meet miracast certification */
378 gint64 block_size = 1920;
379 g_object_set (audiosrc, "blocksize", (gint64) block_size, NULL);
381 audio_convert = gst_element_factory_make ("capssetter", "audio_convert");
382 if (NULL == audio_convert) {
383 GST_ERROR_OBJECT (factory, "failed to create audio convert element");
386 g_object_set (audio_convert, "caps", gst_caps_new_simple("audio/x-lpcm",
387 "width", G_TYPE_INT, 16,
388 "rate", G_TYPE_INT, 48000,
389 "channels", G_TYPE_INT, 2,
390 "dynamic_range", G_TYPE_INT, 0,
391 "emphasis", G_TYPE_BOOLEAN, FALSE,
392 "mute", G_TYPE_BOOLEAN, FALSE, NULL), NULL);
393 g_object_set (audio_convert, "join", (gboolean)FALSE, NULL);
394 g_object_set (audio_convert, "replace", (gboolean)TRUE, NULL);
396 acaps2 = gst_element_factory_make ("capsfilter", "audiocaps2");
397 if (NULL == acaps2) {
398 GST_ERROR_OBJECT (factory, "failed to create audio capsilfter element");
401 /* In case of LPCM, uses big endian */
402 g_object_set (G_OBJECT (acaps2), "caps",
403 gst_caps_new_simple ("audio/x-raw", "format", G_TYPE_STRING, "S16BE",
404 /* In case of LPCM, uses big endian */
405 "rate", G_TYPE_INT, 48000,
406 "channels", G_TYPE_INT, 2, NULL), NULL);
409 /* create audio caps element */
410 acaps = gst_element_factory_make ("capsfilter", "audiocaps");
412 GST_ERROR_OBJECT (factory, "failed to create audio capsilfter element");
416 if (priv->audio_channels == GST_WFD_CHANNEL_2)
418 else if (priv->audio_channels == GST_WFD_CHANNEL_4)
420 else if (priv->audio_channels == GST_WFD_CHANNEL_6)
422 else if (priv->audio_channels == GST_WFD_CHANNEL_8)
427 if (priv->audio_freq == GST_WFD_FREQ_44100)
429 else if (priv->audio_freq == GST_WFD_FREQ_48000)
434 if (priv->audio_codec == GST_WFD_AUDIO_LPCM) {
435 g_object_set (G_OBJECT (acaps), "caps",
436 gst_caps_new_simple ("audio/x-lpcm", "width", G_TYPE_INT, 16,
437 "rate", G_TYPE_INT, 48000,
438 "channels", G_TYPE_INT, 2,
439 "dynamic_range", G_TYPE_INT, 0,
440 "emphasis", G_TYPE_BOOLEAN, FALSE,
441 "mute", G_TYPE_BOOLEAN, FALSE, NULL), NULL);
442 } else if ((priv->audio_codec == GST_WFD_AUDIO_AAC)
443 || (priv->audio_codec == GST_WFD_AUDIO_AC3)) {
444 g_object_set (G_OBJECT (acaps), "caps", gst_caps_new_simple ("audio/x-raw",
445 "endianness", G_TYPE_INT, 1234, "signed", G_TYPE_BOOLEAN, TRUE,
446 "depth", G_TYPE_INT, 16, "rate", G_TYPE_INT, freq, "channels",
447 G_TYPE_INT, channels, NULL), NULL);
450 if (priv->audio_codec == GST_WFD_AUDIO_AAC) {
451 acodec = g_strdup (priv->audio_encoder_aac);
453 } else if (priv->audio_codec == GST_WFD_AUDIO_AC3) {
454 acodec = g_strdup (priv->audio_encoder_ac3);
456 } else if (priv->audio_codec == GST_WFD_AUDIO_LPCM) {
457 GST_DEBUG_OBJECT (factory, "No codec required, raw data will be sent");
460 GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
465 aenc = gst_element_factory_make (acodec, "audioenc");
467 GST_ERROR_OBJECT (factory, "failed to create audio encoder element");
471 g_object_set (aenc, "compliance", -2, NULL);
472 g_object_set (aenc, "tolerance", 400000000, NULL);
473 g_object_set (aenc, "bitrate", (guint) 128000, NULL);
474 g_object_set (aenc, "rate-control", 2, NULL);
476 aqueue = gst_element_factory_make ("queue", "audio-queue");
478 GST_ERROR_OBJECT (factory, "failed to create audio queue element");
482 gst_bin_add_many (srcbin, audiosrc, acaps, aenc, aqueue, NULL);
484 if (!gst_element_link_many (audiosrc, acaps, aenc, aqueue, NULL)) {
485 GST_ERROR_OBJECT (factory, "Failed to link audio src elements...");
489 aqueue = gst_element_factory_make ("queue", "audio-queue");
491 GST_ERROR_OBJECT (factory, "failed to create audio queue element");
495 gst_bin_add_many (srcbin, audiosrc, acaps2, audio_convert, acaps, aqueue, NULL);
497 if (!gst_element_link_many (audiosrc, acaps2, audio_convert, acaps, aqueue, NULL)) {
498 GST_ERROR_OBJECT (factory, "Failed to link audio src elements...");
503 priv->audio_queue = aqueue;
504 if (acodec) g_free (acodec);
505 if (audio_properties_name) gst_structure_free(audio_properties_name);
509 if (acodec) g_free (acodec);
510 if (audio_properties_name) gst_structure_free(audio_properties_name);
515 _rtsp_media_factory_wfd_create_videotest_bin (GstRTSPMediaFactoryWFD * factory,
518 GstElement *videosrc = NULL;
519 GstElement *vcaps = NULL;
520 GstElement *videoconvert = NULL;
521 GstElement *venc_caps = NULL;
522 gchar *vcodec = NULL;
523 GstElement *venc = NULL;
524 GstElement *vparse = NULL;
525 GstElement *vqueue = NULL;
526 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
528 priv = factory->priv;
530 GST_INFO_OBJECT (factory, "picked videotestsrc as video source");
532 videosrc = gst_element_factory_make ("videotestsrc", "videosrc");
533 if (NULL == videosrc) {
534 GST_ERROR_OBJECT (factory, "failed to create ximagesrc element");
538 /* create video caps element */
539 vcaps = gst_element_factory_make ("capsfilter", "videocaps");
541 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
545 g_object_set (G_OBJECT (vcaps), "caps",
546 gst_caps_new_simple ("video/x-raw",
547 "format", G_TYPE_STRING, "I420",
548 "width", G_TYPE_INT, priv->video_width,
549 "height", G_TYPE_INT, priv->video_height,
550 "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
553 /* create video convert element */
554 videoconvert = gst_element_factory_make ("videoconvert", "videoconvert");
555 if (NULL == videoconvert) {
556 GST_ERROR_OBJECT (factory, "failed to create video videoconvert element");
560 venc_caps = gst_element_factory_make ("capsfilter", "venc_caps");
561 if (NULL == venc_caps) {
562 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
566 g_object_set (G_OBJECT (venc_caps), "caps",
567 gst_caps_new_simple ("video/x-raw",
568 "format", G_TYPE_STRING, "SN12",
569 "width", G_TYPE_INT, priv->video_width,
570 "height", G_TYPE_INT, priv->video_height,
571 "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
574 if (priv->video_codec == GST_WFD_VIDEO_H264)
575 vcodec = g_strdup (priv->video_encoder);
577 GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
581 venc = gst_element_factory_make (vcodec, "videoenc");
582 if (vcodec) g_free (vcodec);
585 GST_ERROR_OBJECT (factory, "failed to create video encoder element");
589 g_object_set (venc, "aud", 0, NULL);
590 g_object_set (venc, "byte-stream", 1, NULL);
591 g_object_set (venc, "bitrate", 512, NULL);
593 vparse = gst_element_factory_make ("h264parse", "videoparse");
594 if (NULL == vparse) {
595 GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
598 g_object_set (vparse, "config-interval", 1, NULL);
600 vqueue = gst_element_factory_make ("queue", "video-queue");
602 GST_ERROR_OBJECT (factory, "failed to create video queue element");
606 gst_bin_add_many (srcbin, videosrc, vcaps, videoconvert, venc_caps, venc, vparse, vqueue, NULL);
607 if (!gst_element_link_many (videosrc, vcaps, videoconvert, venc_caps, venc, vparse, vqueue, NULL)) {
608 GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
612 priv->video_queue = vqueue;
621 _rtsp_media_factory_wfd_create_waylandsrc_bin (GstRTSPMediaFactoryWFD * factory,
624 GstElement *videosrc = NULL;
625 GstElement *vcaps = NULL;
626 gchar *vcodec = NULL;
627 GstElement *venc = NULL;
628 GstElement *vparse = NULL;
629 GstElement *vqueue = NULL;
630 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
632 priv = factory->priv;
634 GST_INFO_OBJECT (factory, "picked waylandsrc as video source");
636 videosrc = gst_element_factory_make ("waylandsrc", "videosrc");
637 if (NULL == videosrc) {
638 GST_ERROR_OBJECT (factory, "failed to create ximagesrc element");
642 /* create video caps element */
643 vcaps = gst_element_factory_make ("capsfilter", "videocaps");
645 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
649 g_object_set (G_OBJECT (vcaps), "caps",
650 gst_caps_new_simple ("video/x-raw",
651 "format", G_TYPE_STRING, "SN12",
652 "width", G_TYPE_INT, priv->video_width,
653 "height", G_TYPE_INT, priv->video_height,
654 "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
657 if (priv->video_codec == GST_WFD_VIDEO_H264)
658 vcodec = g_strdup (priv->video_encoder);
660 GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
664 venc = gst_element_factory_make (vcodec, "videoenc");
665 if (vcodec) g_free (vcodec);
668 GST_ERROR_OBJECT (factory, "failed to create video encoder element");
672 g_object_set (venc, "aud", 0, NULL);
673 g_object_set (venc, "byte-stream", 1, NULL);
674 g_object_set (venc, "bitrate", 512, NULL);
676 vparse = gst_element_factory_make ("h264parse", "videoparse");
677 if (NULL == vparse) {
678 GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
681 g_object_set (vparse, "config-interval", 1, NULL);
683 vqueue = gst_element_factory_make ("queue", "video-queue");
685 GST_ERROR_OBJECT (factory, "failed to create video queue element");
689 gst_bin_add_many (srcbin, videosrc, vcaps, venc, vparse, vqueue, NULL);
690 if (!gst_element_link_many (videosrc, vcaps, venc, vparse, vqueue, NULL)) {
691 GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
695 priv->video_queue = vqueue;
704 _rtsp_media_factory_wfd_create_camera_capture_bin (GstRTSPMediaFactoryWFD *
705 factory, GstBin * srcbin)
707 GstElement *videosrc = NULL;
708 GstElement *vcaps = NULL;
709 GstElement *venc = NULL;
710 GstElement *vparse = NULL;
711 GstElement *vqueue = NULL;
712 gchar *vcodec = NULL;
713 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
715 priv = factory->priv;
717 videosrc = gst_element_factory_make ("camerasrc", "videosrc");
718 if (NULL == videosrc) {
719 GST_ERROR_OBJECT (factory, "failed to create camerasrc element");
723 /* create video caps element */
724 vcaps = gst_element_factory_make ("capsfilter", "videocaps");
726 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
730 GST_INFO_OBJECT (factory, "picked camerasrc as video source");
731 g_object_set (G_OBJECT (vcaps), "caps",
732 gst_caps_new_simple ("video/x-raw",
733 "width", G_TYPE_INT, priv->video_width,
734 "height", G_TYPE_INT, priv->video_height,
735 "format", G_TYPE_STRING, "SN12",
736 "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
739 if (priv->video_codec == GST_WFD_VIDEO_H264)
740 vcodec = g_strdup (priv->video_encoder);
742 GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
746 venc = gst_element_factory_make (vcodec, "videoenc");
747 if (vcodec) g_free (vcodec);
750 GST_ERROR_OBJECT (factory, "failed to create video encoder element");
754 g_object_set (venc, "bitrate", priv->video_bitrate, NULL);
755 g_object_set (venc, "byte-stream", 1, NULL);
756 g_object_set (venc, "append-dci", 1, NULL);
758 vparse = gst_element_factory_make ("h264parse", "videoparse");
759 if (NULL == vparse) {
760 GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
763 g_object_set (vparse, "config-interval", 1, NULL);
765 vqueue = gst_element_factory_make ("queue", "video-queue");
767 GST_ERROR_OBJECT (factory, "failed to create video queue element");
771 gst_bin_add_many (srcbin, videosrc, vcaps, venc, vparse, vqueue, NULL);
773 if (!gst_element_link_many (videosrc, vcaps, venc, vparse, vqueue, NULL)) {
774 GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
778 priv->video_queue = vqueue;
787 _rtsp_media_factory_wfd_create_xcapture_bin (GstRTSPMediaFactoryWFD * factory,
790 GstElement *videosrc = NULL;
791 GstElement *vcaps = NULL;
792 GstElement *venc_caps = NULL;
793 GstElement *videoconvert = NULL, *videoscale = NULL;
794 gchar *vcodec = NULL;
795 GstElement *venc = NULL;
796 GstElement *vparse = NULL;
797 GstElement *vqueue = NULL;
798 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
800 priv = factory->priv;
802 GST_INFO_OBJECT (factory, "picked ximagesrc as video source");
804 videosrc = gst_element_factory_make ("ximagesrc", "videosrc");
805 if (NULL == videosrc) {
806 GST_ERROR_OBJECT (factory, "failed to create ximagesrc element");
810 videoscale = gst_element_factory_make ("videoscale", "videoscale");
811 if (NULL == videoscale) {
812 GST_ERROR_OBJECT (factory, "failed to create videoscale element");
816 videoconvert = gst_element_factory_make ("videoconvert", "videoconvert");
817 if (NULL == videoconvert) {
818 GST_ERROR_OBJECT (factory, "failed to create videoconvert element");
822 /* create video caps element */
823 vcaps = gst_element_factory_make ("capsfilter", "videocaps");
825 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
829 g_object_set (G_OBJECT (vcaps), "caps",
830 gst_caps_new_simple ("video/x-raw",
831 "width", G_TYPE_INT, priv->video_width,
832 "height", G_TYPE_INT, priv->video_height,
833 "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
836 if (priv->video_codec == GST_WFD_VIDEO_H264)
837 vcodec = g_strdup (priv->video_encoder);
839 GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
843 venc = gst_element_factory_make (vcodec, "videoenc");
844 if (vcodec) g_free (vcodec);
847 GST_ERROR_OBJECT (factory, "failed to create video encoder element");
851 g_object_set (venc, "aud", 0, NULL);
852 g_object_set (venc, "byte-stream", 1, NULL);
853 g_object_set (venc, "bitrate", 512, NULL);
855 venc_caps = gst_element_factory_make ("capsfilter", "venc_caps");
856 if (NULL == venc_caps) {
857 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
861 g_object_set (G_OBJECT (venc_caps), "caps",
862 gst_caps_new_simple ("video/x-h264",
863 "profile", G_TYPE_STRING, "baseline", NULL), NULL);
865 vparse = gst_element_factory_make ("h264parse", "videoparse");
866 if (NULL == vparse) {
867 GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
870 g_object_set (vparse, "config-interval", 1, NULL);
872 vqueue = gst_element_factory_make ("queue", "video-queue");
874 GST_ERROR_OBJECT (factory, "failed to create video queue element");
878 gst_bin_add_many (srcbin, videosrc, videoscale, videoconvert, vcaps, venc,
879 venc_caps, vparse, vqueue, NULL);
880 if (!gst_element_link_many (videosrc, videoscale, videoconvert, vcaps, venc,
881 venc_caps, vparse, vqueue, NULL)) {
882 GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
886 priv->video_queue = vqueue;
895 _rtsp_media_factory_wfd_create_xvcapture_bin (GstRTSPMediaFactoryWFD * factory,
898 GstElement *videosrc = NULL;
899 GstElement *vcaps = NULL;
900 gchar *vcodec = NULL;
901 GstElement *venc = NULL;
902 GstElement *vparse = NULL;
903 GstElement *vqueue = NULL;
904 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
906 priv = factory->priv;
908 GST_INFO_OBJECT (factory, "picked xvimagesrc as video source");
910 videosrc = gst_element_factory_make ("xvimagesrc", "videosrc");
911 if (NULL == videosrc) {
912 GST_ERROR_OBJECT (factory, "failed to create xvimagesrc element");
916 /* create video caps element */
917 vcaps = gst_element_factory_make ("capsfilter", "videocaps");
919 GST_ERROR_OBJECT (factory, "failed to create video capsilfter element");
923 g_object_set (G_OBJECT (vcaps), "caps",
924 gst_caps_new_simple ("video/x-raw",
925 "width", G_TYPE_INT, priv->video_width,
926 "height", G_TYPE_INT, priv->video_height,
927 "format", G_TYPE_STRING, "SN12",
928 "framerate", GST_TYPE_FRACTION, priv->video_framerate, 1, NULL),
931 if (priv->video_codec == GST_WFD_VIDEO_H264) {
932 vcodec = g_strdup (priv->video_encoder);
934 GST_ERROR_OBJECT (factory, "Yet to support other than H264 format");
938 venc = gst_element_factory_make (vcodec, "videoenc");
940 GST_ERROR_OBJECT (factory, "failed to create video encoder element");
943 g_object_set (venc, "bitrate", priv->video_bitrate, NULL);
944 g_object_set (venc, "byte-stream", 1, NULL);
945 g_object_set (venc, "append-dci", 1, NULL);
946 g_object_set (venc, "idr-period", 120, NULL);
947 g_object_set (venc, "skip-inbuf", priv->video_enc_skip_inbuf_value, NULL);
949 vparse = gst_element_factory_make ("h264parse", "videoparse");
950 if (NULL == vparse) {
951 GST_ERROR_OBJECT (factory, "failed to create h264 parse element");
954 g_object_set (vparse, "config-interval", 1, NULL);
956 vqueue = gst_element_factory_make ("queue", "video-queue");
958 GST_ERROR_OBJECT (factory, "failed to create video queue element");
962 gst_bin_add_many (srcbin, videosrc, vcaps, venc, vparse, vqueue, NULL);
963 if (!gst_element_link_many (videosrc, vcaps, venc, vparse, vqueue, NULL)) {
964 GST_ERROR_OBJECT (factory, "Failed to link video src elements...");
968 priv->video_queue = vqueue;
969 if (vcodec) g_free (vcodec);
974 if (vcodec) g_free (vcodec);
979 _rtsp_media_factory_wfd_create_srcbin (GstRTSPMediaFactoryWFD * factory)
981 GstRTSPMediaFactoryWFDPrivate *priv = NULL;
983 GstBin *srcbin = NULL;
984 GstElement *mux = NULL;
985 GstElement *mux_queue = NULL;
986 GstElement *payload = NULL;
987 GstPad *srcpad = NULL;
988 GstPad *mux_vsinkpad = NULL;
989 GstPad *mux_asinkpad = NULL;
991 priv = factory->priv;
993 /* create source bin */
994 srcbin = GST_BIN (gst_bin_new ("srcbin"));
996 GST_ERROR_OBJECT (factory, "failed to create source bin...");
1000 /* create video src element */
1001 switch (priv->videosrc_type) {
1002 case GST_WFD_VSRC_XIMAGESRC:
1003 if (!_rtsp_media_factory_wfd_create_xcapture_bin (factory, srcbin)) {
1004 GST_ERROR_OBJECT (factory, "failed to create xcapture bin...");
1008 case GST_WFD_VSRC_XVIMAGESRC:
1009 if (!_rtsp_media_factory_wfd_create_xvcapture_bin (factory, srcbin)) {
1010 GST_ERROR_OBJECT (factory, "failed to create xvcapture bin...");
1014 case GST_WFD_VSRC_CAMERASRC:
1015 if (!_rtsp_media_factory_wfd_create_camera_capture_bin (factory, srcbin)) {
1016 GST_ERROR_OBJECT (factory, "failed to create camera capture bin...");
1020 case GST_WFD_VSRC_VIDEOTESTSRC:
1021 if (!_rtsp_media_factory_wfd_create_videotest_bin (factory, srcbin)) {
1022 GST_ERROR_OBJECT (factory, "failed to create videotestsrc bin...");
1026 case GST_WFD_VSRC_WAYLANDSRC:
1027 if (!_rtsp_media_factory_wfd_create_waylandsrc_bin (factory, srcbin)) {
1028 GST_ERROR_OBJECT (factory, "failed to create videotestsrc bin...");
1033 GST_ERROR_OBJECT (factory, "unknow mode selected...");
1037 mux = gst_element_factory_make ("mpegtsmux", "tsmux");
1039 GST_ERROR_OBJECT (factory, "failed to create muxer element");
1043 g_object_set (mux, "wfd-mode", TRUE, NULL);
1045 mux_queue = gst_element_factory_make ("queue", "muxer-queue");
1047 GST_ERROR_OBJECT (factory, "failed to create muxer-queue element");
1051 g_object_set (mux_queue, "max-size-buffers", 20000, NULL);
1053 payload = gst_element_factory_make ("rtpmp2tpay", "pay0");
1055 GST_ERROR_OBJECT (factory, "failed to create payload element");
1059 g_object_set (payload, "pt", 33, NULL);
1060 g_object_set (payload, "mtu", priv->mtu_size, NULL);
1061 g_object_set (payload, "rtp-flush", (gboolean) TRUE, NULL);
1063 gst_bin_add_many (srcbin, mux, mux_queue, payload, NULL);
1065 if (!gst_element_link_many (mux, mux_queue, payload, NULL)) {
1066 GST_ERROR_OBJECT (factory, "Failed to link muxer & payload...");
1070 /* request video sink pad from muxer, which has elementary pid 0x1011 */
1071 mux_vsinkpad = gst_element_get_request_pad (mux, "sink_4113");
1072 if (!mux_vsinkpad) {
1073 GST_ERROR_OBJECT (factory, "Failed to get sink pad from muxer...");
1077 /* request srcpad from video queue */
1078 srcpad = gst_element_get_static_pad (priv->video_queue, "src");
1080 GST_ERROR_OBJECT (factory, "Failed to get srcpad from video queue...");
1084 if (gst_pad_link (srcpad, mux_vsinkpad) != GST_PAD_LINK_OK) {
1085 GST_ERROR_OBJECT (factory,
1086 "Failed to link video queue src pad & muxer video sink pad...");
1090 gst_object_unref (mux_vsinkpad);
1091 gst_object_unref (srcpad);
1094 /* create audio source elements & add to pipeline */
1095 if (!_rtsp_media_factory_wfd_create_audio_capture_bin (factory, srcbin))
1098 /* request audio sink pad from muxer, which has elementary pid 0x1100 */
1099 mux_asinkpad = gst_element_get_request_pad (mux, "sink_4352");
1100 if (!mux_asinkpad) {
1101 GST_ERROR_OBJECT (factory, "Failed to get sinkpad from muxer...");
1105 /* request srcpad from audio queue */
1106 srcpad = gst_element_get_static_pad (priv->audio_queue, "src");
1108 GST_ERROR_OBJECT (factory, "Failed to get srcpad from audio queue...");
1112 /* link audio queue's srcpad & muxer sink pad */
1113 if (gst_pad_link (srcpad, mux_asinkpad) != GST_PAD_LINK_OK) {
1114 GST_ERROR_OBJECT (factory,
1115 "Failed to link audio queue src pad & muxer audio sink pad...");
1118 gst_object_unref (mux_asinkpad);
1119 gst_object_unref (srcpad);
1123 GstPad *pad_probe = NULL;
1124 pad_probe = gst_element_get_static_pad (mux, "src");
1126 if (NULL == pad_probe) {
1127 GST_INFO_OBJECT (factory, "pad for probe not created");
1129 GST_INFO_OBJECT (factory, "pad for probe SUCCESSFUL");
1131 gst_pad_add_probe (pad_probe, GST_PAD_PROBE_TYPE_BUFFER,
1132 rtsp_media_wfd_dump_data, factory, NULL);
1135 GST_DEBUG_OBJECT (factory, "successfully created source bin...");
1137 return GST_ELEMENT_CAST (srcbin);
1140 GST_ERROR_OBJECT (factory, "Failed to create pipeline");
1145 rtsp_media_factory_wfd_create_element (GstRTSPMediaFactory * factory,
1146 const GstRTSPUrl * url)
1148 GstRTSPMediaFactoryWFD *_factory = GST_RTSP_MEDIA_FACTORY_WFD_CAST (factory);
1149 GstElement *element = NULL;
1151 GST_RTSP_MEDIA_FACTORY_WFD_LOCK (factory);
1153 element = _rtsp_media_factory_wfd_create_srcbin (_factory);
1155 GST_RTSP_MEDIA_FACTORY_WFD_UNLOCK (factory);
1160 static GstRTSPMedia *
1161 rtsp_media_factory_wfd_construct (GstRTSPMediaFactory * factory,
1162 const GstRTSPUrl * url)
1164 GstRTSPMedia *media;
1165 GstElement *element, *pipeline;
1166 GstRTSPMediaFactoryClass *klass;
1168 klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory);
1170 if (!klass->create_pipeline)
1173 element = gst_rtsp_media_factory_create_element (factory, url);
1174 if (element == NULL)
1177 /* create a new empty media */
1178 media = gst_rtsp_media_new (element);
1180 gst_rtsp_media_collect_streams (media);
1182 pipeline = klass->create_pipeline (factory, media);
1183 if (pipeline == NULL)
1191 g_critical ("no create_pipeline function");
1196 g_critical ("could not create element");
1201 g_critical ("can't create pipeline");
1202 g_object_unref (media);