Finish sender pipeline

parent cc5a3511
PKGCONFIG = $(shell which pkg-config)
GST_CFLAGS = $(shell $(PKGCONFIG) --cflags gstreamer-1.0)
GST_LDFLAGS = $(shell $(PKGCONFIG) --libs gstreamer-1.0)
all: sender
$(CC) $(CC_FLAGS) \
sender.c -o $@ \
rm -f sender
......@@ -16,9 +16,9 @@ typedef struct {
GstElement *rtpbin;
GstElement *encoder;
GstElement *payloader;
GstElement *rtp_udp_sink;
GstElement *rtcp_udp_sink;
GstElement *rtcp_udp_src;
GstElement *rtp_sink;
GstElement *rtcp_sink;
GstElement *rtcp_src;
} RtpData;
#define REMOTE ""
......@@ -35,37 +35,97 @@ main (int argc, char**argv) {
GstBus *bus;
GstStateChangeReturn ret;
AudioEncoding *enc;
GstPad *srcpad, *sinkpad;
/* XXX would need glib-mkenum to get value from string */
const gchar *codec = g_getenv ("CODEC");
const gchar *remote = g_getenv ("REMOTE");
enc = encodings[CODEC];
if (!remote)
remote = REMOTE;
gst_init (argc, argv);
enc = &encodings[CODEC];
gst_init (&argc, &argv);
/* could also use autoaudiosrc in place of pulsesrc*/
data.source = gst_element_factory_make ("pulsesrc", "source");
/* maybe we need to also explicitly add audioconvert and audioresample elements */
data.rtpbin = gst_element_factory_make ("rtpbin", "rtpbin");
/* L16 codecs would need special handling, maybe simply drop it */
data.encoder = gst_element_factory_make (enc.gst_encoder_name, "encoder");
data.payloader = gst_element_factory_make (enc.gst_payloader_name, "payloader");
data.rtp_udp_sink = gst_element_factory_make ("udpsink", "rtp-udp-sink");
data.rtcp_udp_sink = gst_element_factory_make ("udpsink", "rtcp-udp-sink");
data.rtcp_udp_src = gst_element_factory_make ("udpsrc", "rtcp-udp-src");
data.encoder = gst_element_factory_make (enc->gst_encoder_name, "encoder");
data.payloader = gst_element_factory_make (enc->gst_payloader_name, "payloader");
data.rtp_sink = gst_element_factory_make ("udpsink", "rtp-udp-sink");
data.rtcp_sink = gst_element_factory_make ("udpsink", "rtcp-udp-sink");
data.rtcp_src = gst_element_factory_make ("udpsrc", "rtcp-udp-src");
data.pipeline = gst_pipeline_new ("rtp-send-pipeline");
if (!data.pipeline || !data.source || !data.rtpbin ||
!data.encoder || !data.payloader || !data.rtp_udp_sink ||
!data.rtcp_udp_sink || !data.rtcp_udp_src) {
!data.encoder || !data.payloader || !data.rtp_sink ||
!data.rtcp_sink || !data.rtcp_src) {
g_error ("Could not create all elements");
return -1;
/* set udpsrc/udpsink ports */
g_object_set (data.rtp_sink, "port", RTP_PORT_SINK, NULL);
g_object_set (data.rtcp_sink, "port", RTCP_PORT_SINK, NULL);
gst_bin_add_many (GST_BIN (data.pipeline), data.source, data.encoder,
data.payloader, NULL);
gst_bin_add (GST_BIN (data.pipeline), data.rtpbin);
/* set udp sinks and sources for RTP and RTCP */
g_object_set (data.rtp_sink, "port", RTP_PORT_SINK,
"host", REMOTE, NULL);
g_object_set (data.rtcp_sink, "port", RTCP_PORT_SINK,
"host", REMOTE, NULL);
g_object_set (data.rtcp_src, "port", RTCP_PORT_SRC, NULL);
g_object_set (data.rtcp_sink, "async", FALSE, "sync", FALSE, NULL);
gst_bin_add_many (GST_BIN (data.pipeline), data.rtp_sink, data.rtcp_sink,
data.rtcp_src, NULL);
/* request and link the pads, start getting a RTP sinkpad */
sinkpad = gst_element_get_request_pad (data.rtpbin, "send_rtp_sink_0");
srcpad = gst_element_get_static_pad (data.payloader, "src");
if (gst_pad_link (srcpad, sinkpad) != GST_PAD_LINK_OK)
g_error ("Failed to link payloader to rtpbin");
gst_object_unref (srcpad);
gst_object_unref (sinkpad);
/* link RTP srcpad to udpsink */
srcpad = gst_element_get_static_pad (data.rtpbin, "send_rtp_src_0");
sinkpad = gst_element_get_static_pad (data.rtp_sink, "sink");
if (gst_pad_link (srcpad, sinkpad) != GST_PAD_LINK_OK)
g_error ("Failed to link rtpbin to rtpsink");
gst_object_unref (srcpad);
gst_object_unref (sinkpad);
/* RTCP srcpad to udpsink */
srcpad = gst_element_get_request_pad (data.rtpbin, "send_rtcp_src_0");
sinkpad = gst_element_get_static_pad (data.rtcp_sink, "sink");
if (gst_pad_link (srcpad, sinkpad) != GST_PAD_LINK_OK)
g_error ("Failed to link rtpbin to rtcpsink");
gst_object_unref (srcpad);
gst_object_unref (sinkpad);
/* receive RTCP */
srcpad = gst_element_get_static_pad (data.rtcp_src, "src");
sinkpad = gst_element_get_request_pad (data.rtpbin, "recv_rtcp_sink_0");
if (gst_pad_link (srcpad, sinkpad) != GST_PAD_LINK_OK)
g_error ("Failed to link rtcpsrc to rtpbin");
gst_object_unref (srcpad);
gst_object_unref (sinkpad);
/* start the pipeline */
g_print ("Starting sender pipeline\n");
gst_element_set_state (data.pipeline, GST_STATE_PLAYING);
loop = g_main_loop_new (NULL, FALSE);
g_main_loop_run (loop);
g_print ("Stopping sender pipeline");
gst_element_set_state (data.pipeline, GST_STATE_NULL);
gst_object_unref (data.pipeline);
return 0;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment