2 * Copyright (C) 2016 Igalia S.L
3 * @author Philippe Normand <philn@igalia.com>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
23 * An bundling RTP server
24 * creates two sessions and streams audio on one, video on the other, with RTCP
25 * on both sessions. The destination is 127.0.0.1.
27 * The RTP streams are bundled to a single outgoing connection. Same for the RTCP streams.
29 * .-------. .-------. .-------. .------------. .------.
30 * |audiots| |alawenc| |pcmapay| | rtpbin | |funnel|
31 * | src->sink src->sink src->send_rtp_0 send_rtp_0--->sink_0 | .-------.
32 * '-------' '-------' '-------' | | | | |udpsink|
34 * .-------. .---------. | | | | '-------'
35 * |videots| | vrawpay | | | | |
36 * | src------------>sink src->send_rtp_1 send_rtp_1--->sink_1 |
37 * '-------' '---------' | | '------'
40 * |udpsrc| | | .------.
41 * | src->recv_rtcp_0 | |funnel|
42 * '------' | send_rtcp_0-->sink_0 | .-------.
44 * .------. | | | src->sink |
45 * |udpsrc| | | | | '-------'
46 * | src->recv_rtcp_1 | | |
47 * '------' | send_rtcp_1-->sink_1 |
48 * '------------' '------'
53 create_pipeline (void)
55 GstElement *pipeline, *rtpbin, *audiosrc, *audio_encoder,
56 *audio_rtppayloader, *sendrtp_udpsink,
57 *send_rtcp_udpsink, *sendrtcp_funnel, *sendrtp_funnel;
58 GstElement *videosrc, *video_rtppayloader, *time_overlay;
59 gint rtp_udp_port = 5001;
60 gint rtcp_udp_port = 5002;
61 gint recv_audio_rtcp_port = 5003;
62 gint recv_video_rtcp_port = 5004;
63 GstElement *audio_rtcp_udpsrc, *video_rtcp_udpsrc;
65 pipeline = gst_pipeline_new (NULL);
67 rtpbin = gst_element_factory_make ("rtpbin", NULL);
69 audiosrc = gst_element_factory_make ("audiotestsrc", NULL);
70 g_object_set (audiosrc, "is-live", TRUE, NULL);
71 audio_encoder = gst_element_factory_make ("alawenc", NULL);
72 audio_rtppayloader = gst_element_factory_make ("rtppcmapay", NULL);
73 g_object_set (audio_rtppayloader, "pt", 96, NULL);
75 videosrc = gst_element_factory_make ("videotestsrc", NULL);
76 g_object_set (videosrc, "is-live", TRUE, NULL);
77 time_overlay = gst_element_factory_make ("timeoverlay", NULL);
78 video_rtppayloader = gst_element_factory_make ("rtpvrawpay", NULL);
79 g_object_set (video_rtppayloader, "pt", 100, NULL);
82 sendrtcp_funnel = gst_element_factory_make ("funnel", "send_rtcp_funnel");
83 send_rtcp_udpsink = gst_element_factory_make ("udpsink", NULL);
84 g_object_set (send_rtcp_udpsink, "host", "127.0.0.1", NULL);
85 g_object_set (send_rtcp_udpsink, "port", rtcp_udp_port, NULL);
86 g_object_set (send_rtcp_udpsink, "sync", FALSE, NULL);
87 g_object_set (send_rtcp_udpsink, "async", FALSE, NULL);
89 /* outgoing bundled stream */
90 sendrtp_funnel = gst_element_factory_make ("funnel", "send_rtp_funnel");
91 sendrtp_udpsink = gst_element_factory_make ("udpsink", NULL);
92 g_object_set (sendrtp_udpsink, "host", "127.0.0.1", NULL);
93 g_object_set (sendrtp_udpsink, "port", rtp_udp_port, NULL);
94 g_object_set (sendrtp_udpsink, "sync", FALSE, NULL);
95 g_object_set (sendrtp_udpsink, "async", FALSE, NULL);
97 gst_bin_add_many (GST_BIN (pipeline), rtpbin, audiosrc, audio_encoder,
98 audio_rtppayloader, sendrtp_udpsink, send_rtcp_udpsink,
99 sendrtp_funnel, sendrtcp_funnel, videosrc, video_rtppayloader, NULL);
102 gst_bin_add (GST_BIN (pipeline), time_overlay);
104 gst_element_link_many (audiosrc, audio_encoder, audio_rtppayloader, NULL);
105 gst_element_link_pads (audio_rtppayloader, "src", rtpbin, "send_rtp_sink_0");
108 gst_element_link_many (videosrc, time_overlay, video_rtppayloader, NULL);
110 gst_element_link (videosrc, video_rtppayloader);
113 gst_element_link_pads (video_rtppayloader, "src", rtpbin, "send_rtp_sink_1");
115 gst_element_link_pads (sendrtp_funnel, "src", sendrtp_udpsink, "sink");
116 gst_element_link_pads (rtpbin, "send_rtp_src_0", sendrtp_funnel, "sink_%u");
117 gst_element_link_pads (rtpbin, "send_rtp_src_1", sendrtp_funnel, "sink_%u");
118 gst_element_link_pads (sendrtcp_funnel, "src", send_rtcp_udpsink, "sink");
119 gst_element_link_pads (rtpbin, "send_rtcp_src_0", sendrtcp_funnel, "sink_%u");
120 gst_element_link_pads (rtpbin, "send_rtcp_src_1", sendrtcp_funnel, "sink_%u");
122 audio_rtcp_udpsrc = gst_element_factory_make ("udpsrc", NULL);
123 g_object_set (audio_rtcp_udpsrc, "port", recv_audio_rtcp_port, NULL);
124 video_rtcp_udpsrc = gst_element_factory_make ("udpsrc", NULL);
125 g_object_set (video_rtcp_udpsrc, "port", recv_video_rtcp_port, NULL);
126 gst_bin_add_many (GST_BIN (pipeline), audio_rtcp_udpsrc, video_rtcp_udpsrc,
128 gst_element_link_pads (audio_rtcp_udpsrc, "src", rtpbin, "recv_rtcp_sink_0");
129 gst_element_link_pads (video_rtcp_udpsrc, "src", rtpbin, "recv_rtcp_sink_1");
135 * Used to generate informative messages during pipeline startup
138 cb_state (GstBus * bus, GstMessage * message, gpointer data)
140 GstObject *pipe = GST_OBJECT (data);
141 GstState old, new, pending;
142 gst_message_parse_state_changed (message, &old, &new, &pending);
143 if (message->src == pipe) {
144 g_print ("Pipeline %s changed state from %s to %s\n",
145 GST_OBJECT_NAME (message->src),
146 gst_element_state_get_name (old), gst_element_state_get_name (new));
151 main (int argc, char **argv)
157 gst_init (&argc, &argv);
159 loop = g_main_loop_new (NULL, FALSE);
161 pipe = create_pipeline ();
162 bus = gst_element_get_bus (pipe);
163 g_signal_connect (bus, "message::state-changed", G_CALLBACK (cb_state), pipe);
164 gst_bus_add_signal_watch (bus);
165 gst_object_unref (bus);
167 g_print ("starting server pipeline\n");
168 gst_element_set_state (pipe, GST_STATE_PLAYING);
170 g_main_loop_run (loop);
172 g_print ("stopping server pipeline\n");
173 gst_element_set_state (pipe, GST_STATE_NULL);
175 gst_object_unref (pipe);
176 g_main_loop_unref (loop);