Commit f52e16ce authored by Mathieu Duponchelle's avatar Mathieu Duponchelle 🐸 Committed by Mathieu Duponchelle

Revert "rtpbin: receive bundle support"

This reverts commit dcd3ce97.

This functionality was implemented for gstopenwebrtc, but it
turned out this was not actually needed for webrtc bundling
support, as shown in webrtcbin. It also doesn't correspond
to any standards.

This is an API break, but nothing should actually depend on
this, at least not for its initial purpose.

Changes in rtpbin.c were reverted manually, to preserve some
refactoring that had occurred in the original commit.

Fixes #537
parent 05059ce1
......@@ -374,14 +374,6 @@ GstRtpBin *gstrtpbin
guint arg1
</SIGNAL>
<SIGNAL>
<NAME>GstRtpBin::on-bundled-ssrc</NAME>
<RETURNS>guint</RETURNS>
<FLAGS>l</FLAGS>
GstRtpBin *gstrtpbin
guint arg1
</SIGNAL>
<SIGNAL>
<NAME>GstRtpBin::get-internal-storage</NAME>
<RETURNS>GObject*</RETURNS>
......
This diff is collapsed.
......@@ -137,8 +137,6 @@ struct _GstRtpBinClass {
void (*on_new_sender_ssrc) (GstRtpBin *rtpbin, guint session, guint32 ssrc);
void (*on_sender_ssrc_active) (GstRtpBin *rtpbin, guint session, guint32 ssrc);
guint (*on_bundled_ssrc) (GstRtpBin *rtpbin, guint ssrc);
};
GType gst_rtp_bin_get_type (void);
......
......@@ -246,7 +246,6 @@ if USE_PLUGIN_RTPMANAGER
check_rtpmanager = \
elements/rtpbin \
elements/rtpbin_buffer_list \
elements/rtpbundle \
elements/rtpcollision \
elements/rtpjitterbuffer \
elements/rtpmux \
......@@ -619,9 +618,6 @@ elements_rtpfunnel_LDADD = $(GST_PLUGINS_BASE_LIBS) -lgstrtp-$(GST_API_VERSION)
elements_rtpcollision_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(CFLAGS) $(AM_CFLAGS)
elements_rtpcollision_LDADD = $(GST_PLUGINS_BASE_LIBS) $(GST_NET_LIBS) -lgstrtp-$(GST_API_VERSION) $(GIO_LIBS) $(LDADD)
elements_rtpbundle_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(CFLAGS) $(AM_CFLAGS)
elements_rtpbundle_LDADD = $(GST_PLUGINS_BASE_LIBS) -lgstrtp-$(GST_API_VERSION) $(LDADD)
elements_rtpstorage_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(CFLAGS) $(AM_CFLAGS)
elements_rtpstorage_LDADD = $(GST_PLUGINS_BASE_LIBS) $(GST_NET_LIBS) -lgstrtp-$(GST_API_VERSION) $(GIO_LIBS) $(LDADD)
......
......@@ -54,7 +54,6 @@ rgvolume
rtp-payloading
rtpbin
rtpbin_buffer_list
rtpbundle
rtpcollision
rtph261
rtph263
......
This diff is collapsed.
......@@ -53,7 +53,6 @@ good_tests = [
[ 'elements/rtpvp9' ],
[ 'elements/rtpbin' ],
[ 'elements/rtpbin_buffer_list' ],
[ 'elements/rtpbundle' ],
[ 'elements/rtpcollision' ],
[ 'elements/rtpfunnel' ],
[ 'elements/rtpjitterbuffer' ],
......
......@@ -2,5 +2,3 @@ client-PCMA
server-alsasrc-PCMA
client-rtpaux
server-rtpaux
client-rtpbundle
server-rtpbundle
noinst_PROGRAMS = server-alsasrc-PCMA client-PCMA \
client-rtpaux server-rtpaux client-rtpbundle server-rtpbundle
client-rtpaux server-rtpaux
# FIXME 0.11: ignore GValueArray warnings for now until this is sorted
ERROR_CFLAGS=
......@@ -12,14 +12,6 @@ client_rtpaux_SOURCES = client-rtpaux.c
client_rtpaux_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS)
client_rtpaux_LDADD = $(GST_LIBS)
server_rtpbundle_SOURCES = server-rtpbundle.c
server_rtpbundle_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS)
server_rtpbundle_LDADD = $(GST_LIBS)
client_rtpbundle_SOURCES = client-rtpbundle.c
client_rtpbundle_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS)
client_rtpbundle_LDADD = $(GST_LIBS)
server_alsasrc_PCMA_SOURCES = server-alsasrc-PCMA.c
server_alsasrc_PCMA_CFLAGS = $(GST_CFLAGS)
server_alsasrc_PCMA_LDADD = $(GST_LIBS) $(LIBM)
......
/* GStreamer
* Copyright (C) 2016 Igalia S.L
* @author Philippe Normand <philn@igalia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <gst/gst.h>
/*
* RTP bundle receiver
*
* In this example we initially create one RTP session but the incoming RTP
* and RTCP streams actually bundle 2 different media type, one audio stream
* and one video stream. We are notified of the discovery of the streams by
* the on-bundled-ssrc rtpbin signal. In the handler we decide to assign the
* first SSRC to the (existing) audio session and the second SSRC to a new
* session (id: 1).
*
* .-------. .----------. .-----------. .-------. .-------------.
* RTP |udpsrc | | rtpbin | | pcmadepay | |alawdec| |autoaudiosink|
* port=5001 | src->recv_rtp_0 recv_rtp_0->sink src->sink src->sink |
* '-------' | | '-----------' '-------' '-------------'
* | |
* | | .-------.
* | | |udpsink| RTCP
* | send_rtcp_0->sink | port=5003
* .-------. | | '-------' sync=false
* RTCP |udpsrc | | | async=false
* port=5002 | src->recv_rtcp_0 |
* '-------' | |
* | |
* | | .---------. .-------------.
* | | |vrawdepay| |autovideosink|
* | recv_rtp_1->sink src->sink |
* | | '---------' '-------------'
* | |
* | | .-------.
* | | |udpsink| RTCP
* | send_rtcp_1->sink | port=5004
* | | '-------' sync=false
* | | async=false
* | |
* '----------'
*
*/
static gboolean
plug_video_rtcp_sender (gpointer user_data)
{
gint send_video_rtcp_port = 5004;
GstElement *rtpbin = GST_ELEMENT_CAST (user_data);
GstElement *send_video_rtcp_udpsink;
GstElement *pipeline =
GST_ELEMENT_CAST (gst_object_get_parent (GST_OBJECT (rtpbin)));
send_video_rtcp_udpsink = gst_element_factory_make ("udpsink", NULL);
g_object_set (send_video_rtcp_udpsink, "host", "127.0.0.1", NULL);
g_object_set (send_video_rtcp_udpsink, "port", send_video_rtcp_port, NULL);
g_object_set (send_video_rtcp_udpsink, "sync", FALSE, NULL);
g_object_set (send_video_rtcp_udpsink, "async", FALSE, NULL);
gst_bin_add (GST_BIN (pipeline), send_video_rtcp_udpsink);
gst_element_link_pads (rtpbin, "send_rtcp_src_1", send_video_rtcp_udpsink,
"sink");
gst_element_sync_state_with_parent (send_video_rtcp_udpsink);
gst_object_unref (pipeline);
gst_object_unref (rtpbin);
return G_SOURCE_REMOVE;
}
static void
on_rtpbinreceive_pad_added (GstElement * rtpbin, GstPad * new_pad,
gpointer data)
{
GstElement *pipeline = GST_ELEMENT (data);
gchar *pad_name = gst_pad_get_name (new_pad);
if (g_str_has_prefix (pad_name, "recv_rtp_src_")) {
GstCaps *caps = gst_pad_get_current_caps (new_pad);
GstStructure *s = gst_caps_get_structure (caps, 0);
const gchar *media_type = gst_structure_get_string (s, "media");
gchar *depayloader_name = g_strdup_printf ("%s_rtpdepayloader", media_type);
GstElement *rtpdepayloader =
gst_bin_get_by_name (GST_BIN (pipeline), depayloader_name);
GstPad *sinkpad;
g_free (depayloader_name);
sinkpad = gst_element_get_static_pad (rtpdepayloader, "sink");
gst_pad_link (new_pad, sinkpad);
gst_object_unref (sinkpad);
gst_object_unref (rtpdepayloader);
gst_caps_unref (caps);
if (g_str_has_prefix (pad_name, "recv_rtp_src_1")) {
g_timeout_add (0, plug_video_rtcp_sender, gst_object_ref (rtpbin));
}
}
g_free (pad_name);
}
static guint
on_bundled_ssrc (GstElement * rtpbin, guint ssrc, gpointer user_data)
{
static gboolean create_session = FALSE;
guint session_id = 0;
if (create_session) {
session_id = 1;
} else {
create_session = TRUE;
/* use existing session 0, a new session will be created for the next discovered bundled SSRC */
}
return session_id;
}
static GstCaps *
on_request_pt_map (GstElement * rtpbin, guint session_id, guint pt,
gpointer user_data)
{
GstCaps *caps = NULL;
if (pt == 96) {
caps =
gst_caps_from_string
("application/x-rtp,media=(string)audio,encoding-name=(string)PCMA,clock-rate=(int)8000");
} else if (pt == 100) {
caps =
gst_caps_from_string
("application/x-rtp,media=(string)video,encoding-name=(string)RAW,clock-rate=(int)90000,sampling=(string)\"YCbCr-4:2:0\",depth=(string)8,width=(string)320,height=(string)240");
}
return caps;
}
static GstElement *
create_pipeline (void)
{
GstElement *pipeline, *rtpbin, *recv_rtp_udpsrc, *recv_rtcp_udpsrc,
*audio_rtpdepayloader, *audio_decoder, *audio_sink, *video_rtpdepayloader,
*video_sink, *send_audio_rtcp_udpsink;
GstCaps *rtpcaps;
gint rtp_udp_port = 5001;
gint rtcp_udp_port = 5002;
gint send_audio_rtcp_port = 5003;
pipeline = gst_pipeline_new (NULL);
rtpbin = gst_element_factory_make ("rtpbin", NULL);
g_object_set (rtpbin, "latency", 200, NULL);
g_signal_connect (rtpbin, "on-bundled-ssrc",
G_CALLBACK (on_bundled_ssrc), NULL);
g_signal_connect (rtpbin, "request-pt-map",
G_CALLBACK (on_request_pt_map), NULL);
g_signal_connect (rtpbin, "pad-added",
G_CALLBACK (on_rtpbinreceive_pad_added), pipeline);
gst_bin_add (GST_BIN (pipeline), rtpbin);
recv_rtp_udpsrc = gst_element_factory_make ("udpsrc", NULL);
g_object_set (recv_rtp_udpsrc, "port", rtp_udp_port, NULL);
rtpcaps = gst_caps_from_string ("application/x-rtp");
g_object_set (recv_rtp_udpsrc, "caps", rtpcaps, NULL);
gst_caps_unref (rtpcaps);
recv_rtcp_udpsrc = gst_element_factory_make ("udpsrc", NULL);
g_object_set (recv_rtcp_udpsrc, "port", rtcp_udp_port, NULL);
audio_rtpdepayloader =
gst_element_factory_make ("rtppcmadepay", "audio_rtpdepayloader");
audio_decoder = gst_element_factory_make ("alawdec", NULL);
audio_sink = gst_element_factory_make ("autoaudiosink", NULL);
video_rtpdepayloader =
gst_element_factory_make ("rtpvrawdepay", "video_rtpdepayloader");
video_sink = gst_element_factory_make ("autovideosink", NULL);
gst_bin_add_many (GST_BIN (pipeline), recv_rtp_udpsrc, recv_rtcp_udpsrc,
audio_rtpdepayloader, audio_decoder, audio_sink, video_rtpdepayloader,
video_sink, NULL);
gst_element_link_pads (audio_rtpdepayloader, "src", audio_decoder, "sink");
gst_element_link (audio_decoder, audio_sink);
gst_element_link_pads (video_rtpdepayloader, "src", video_sink, "sink");
/* request a single receiving RTP session. */
gst_element_link_pads (recv_rtcp_udpsrc, "src", rtpbin, "recv_rtcp_sink_0");
gst_element_link_pads (recv_rtp_udpsrc, "src", rtpbin, "recv_rtp_sink_0");
send_audio_rtcp_udpsink = gst_element_factory_make ("udpsink", NULL);
g_object_set (send_audio_rtcp_udpsink, "host", "127.0.0.1", NULL);
g_object_set (send_audio_rtcp_udpsink, "port", send_audio_rtcp_port, NULL);
g_object_set (send_audio_rtcp_udpsink, "sync", FALSE, NULL);
g_object_set (send_audio_rtcp_udpsink, "async", FALSE, NULL);
gst_bin_add (GST_BIN (pipeline), send_audio_rtcp_udpsink);
gst_element_link_pads (rtpbin, "send_rtcp_src_0", send_audio_rtcp_udpsink,
"sink");
return pipeline;
}
/*
* Used to generate informative messages during pipeline startup
*/
static void
cb_state (GstBus * bus, GstMessage * message, gpointer data)
{
GstObject *pipe = GST_OBJECT (data);
GstState old, new, pending;
gst_message_parse_state_changed (message, &old, &new, &pending);
if (message->src == pipe) {
g_print ("Pipeline %s changed state from %s to %s\n",
GST_OBJECT_NAME (message->src),
gst_element_state_get_name (old), gst_element_state_get_name (new));
if (old == GST_STATE_PAUSED && new == GST_STATE_PLAYING)
GST_DEBUG_BIN_TO_DOT_FILE (GST_BIN (pipe), GST_DEBUG_GRAPH_SHOW_ALL,
GST_OBJECT_NAME (message->src));
}
}
int
main (int argc, char **argv)
{
GstElement *pipe;
GstBus *bus;
GMainLoop *loop;
gst_init (&argc, &argv);
loop = g_main_loop_new (NULL, FALSE);
pipe = create_pipeline ();
bus = gst_element_get_bus (pipe);
g_signal_connect (bus, "message::state-changed", G_CALLBACK (cb_state), pipe);
gst_bus_add_signal_watch (bus);
gst_object_unref (bus);
g_print ("starting server pipeline\n");
gst_element_set_state (pipe, GST_STATE_PLAYING);
g_main_loop_run (loop);
g_print ("stopping server pipeline\n");
gst_element_set_state (pipe, GST_STATE_NULL);
gst_object_unref (pipe);
g_main_loop_unref (loop);
return 0;
}
......@@ -3,8 +3,6 @@ rtp_progs = [
'client-PCMA',
'client-rtpaux',
'server-rtpaux',
'client-rtpbundle',
'server-rtpbundle',
]
foreach prog : rtp_progs
......
/* GStreamer
* Copyright (C) 2016 Igalia S.L
* @author Philippe Normand <philn@igalia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <gst/gst.h>
/*
* An bundling RTP server
* creates two sessions and streams audio on one, video on the other, with RTCP
* on both sessions. The destination is 127.0.0.1.
*
* The RTP streams are bundled to a single outgoing connection. Same for the RTCP streams.
*
* .-------. .-------. .-------. .------------. .------.
* |audiots| |alawenc| |pcmapay| | rtpbin | |funnel|
* | src->sink src->sink src->send_rtp_0 send_rtp_0--->sink_0 | .-------.
* '-------' '-------' '-------' | | | | |udpsink|
* | | | src->sink |
* .-------. .---------. | | | | '-------'
* |videots| | vrawpay | | | | |
* | src------------>sink src->send_rtp_1 send_rtp_1--->sink_1 |
* '-------' '---------' | | '------'
* | |
* .------. | |
* |udpsrc| | | .------.
* | src->recv_rtcp_0 | |funnel|
* '------' | send_rtcp_0-->sink_0 | .-------.
* | | | | |udpsink|
* .------. | | | src->sink |
* |udpsrc| | | | | '-------'
* | src->recv_rtcp_1 | | |
* '------' | send_rtcp_1-->sink_1 |
* '------------' '------'
*
*/
static GstElement *
create_pipeline (void)
{
GstElement *pipeline, *rtpbin, *audiosrc, *audio_encoder,
*audio_rtppayloader, *sendrtp_udpsink,
*send_rtcp_udpsink, *sendrtcp_funnel, *sendrtp_funnel;
GstElement *videosrc, *video_rtppayloader, *time_overlay;
gint rtp_udp_port = 5001;
gint rtcp_udp_port = 5002;
gint recv_audio_rtcp_port = 5003;
gint recv_video_rtcp_port = 5004;
GstElement *audio_rtcp_udpsrc, *video_rtcp_udpsrc;
pipeline = gst_pipeline_new (NULL);
rtpbin = gst_element_factory_make ("rtpbin", NULL);
audiosrc = gst_element_factory_make ("audiotestsrc", NULL);
g_object_set (audiosrc, "is-live", TRUE, NULL);
audio_encoder = gst_element_factory_make ("alawenc", NULL);
audio_rtppayloader = gst_element_factory_make ("rtppcmapay", NULL);
g_object_set (audio_rtppayloader, "pt", 96, NULL);
videosrc = gst_element_factory_make ("videotestsrc", NULL);
g_object_set (videosrc, "is-live", TRUE, NULL);
time_overlay = gst_element_factory_make ("timeoverlay", NULL);
video_rtppayloader = gst_element_factory_make ("rtpvrawpay", NULL);
g_object_set (video_rtppayloader, "pt", 100, NULL);
/* muxed rtcp */
sendrtcp_funnel = gst_element_factory_make ("funnel", "send_rtcp_funnel");
send_rtcp_udpsink = gst_element_factory_make ("udpsink", NULL);
g_object_set (send_rtcp_udpsink, "host", "127.0.0.1", NULL);
g_object_set (send_rtcp_udpsink, "port", rtcp_udp_port, NULL);
g_object_set (send_rtcp_udpsink, "sync", FALSE, NULL);
g_object_set (send_rtcp_udpsink, "async", FALSE, NULL);
/* outgoing bundled stream */
sendrtp_funnel = gst_element_factory_make ("funnel", "send_rtp_funnel");
sendrtp_udpsink = gst_element_factory_make ("udpsink", NULL);
g_object_set (sendrtp_udpsink, "host", "127.0.0.1", NULL);
g_object_set (sendrtp_udpsink, "port", rtp_udp_port, NULL);
g_object_set (sendrtp_udpsink, "sync", FALSE, NULL);
g_object_set (sendrtp_udpsink, "async", FALSE, NULL);
gst_bin_add_many (GST_BIN (pipeline), rtpbin, audiosrc, audio_encoder,
audio_rtppayloader, sendrtp_udpsink, send_rtcp_udpsink,
sendrtp_funnel, sendrtcp_funnel, videosrc, video_rtppayloader, NULL);
if (time_overlay)
gst_bin_add (GST_BIN (pipeline), time_overlay);
gst_element_link_many (audiosrc, audio_encoder, audio_rtppayloader, NULL);
gst_element_link_pads (audio_rtppayloader, "src", rtpbin, "send_rtp_sink_0");
if (time_overlay) {
gst_element_link_many (videosrc, time_overlay, video_rtppayloader, NULL);
} else {
gst_element_link (videosrc, video_rtppayloader);
}
gst_element_link_pads (video_rtppayloader, "src", rtpbin, "send_rtp_sink_1");
gst_element_link_pads (sendrtp_funnel, "src", sendrtp_udpsink, "sink");
gst_element_link_pads (rtpbin, "send_rtp_src_0", sendrtp_funnel, "sink_%u");
gst_element_link_pads (rtpbin, "send_rtp_src_1", sendrtp_funnel, "sink_%u");
gst_element_link_pads (sendrtcp_funnel, "src", send_rtcp_udpsink, "sink");
gst_element_link_pads (rtpbin, "send_rtcp_src_0", sendrtcp_funnel, "sink_%u");
gst_element_link_pads (rtpbin, "send_rtcp_src_1", sendrtcp_funnel, "sink_%u");
audio_rtcp_udpsrc = gst_element_factory_make ("udpsrc", NULL);
g_object_set (audio_rtcp_udpsrc, "port", recv_audio_rtcp_port, NULL);
video_rtcp_udpsrc = gst_element_factory_make ("udpsrc", NULL);
g_object_set (video_rtcp_udpsrc, "port", recv_video_rtcp_port, NULL);
gst_bin_add_many (GST_BIN (pipeline), audio_rtcp_udpsrc, video_rtcp_udpsrc,
NULL);
gst_element_link_pads (audio_rtcp_udpsrc, "src", rtpbin, "recv_rtcp_sink_0");
gst_element_link_pads (video_rtcp_udpsrc, "src", rtpbin, "recv_rtcp_sink_1");
return pipeline;
}
/*
* Used to generate informative messages during pipeline startup
*/
static void
cb_state (GstBus * bus, GstMessage * message, gpointer data)
{
GstObject *pipe = GST_OBJECT (data);
GstState old, new, pending;
gst_message_parse_state_changed (message, &old, &new, &pending);
if (message->src == pipe) {
g_print ("Pipeline %s changed state from %s to %s\n",
GST_OBJECT_NAME (message->src),
gst_element_state_get_name (old), gst_element_state_get_name (new));
}
}
int
main (int argc, char **argv)
{
GstElement *pipe;
GstBus *bus;
GMainLoop *loop;
gst_init (&argc, &argv);
loop = g_main_loop_new (NULL, FALSE);
pipe = create_pipeline ();
bus = gst_element_get_bus (pipe);
g_signal_connect (bus, "message::state-changed", G_CALLBACK (cb_state), pipe);
gst_bus_add_signal_watch (bus);
gst_object_unref (bus);
g_print ("starting server pipeline\n");
gst_element_set_state (pipe, GST_STATE_PLAYING);
g_main_loop_run (loop);
g_print ("stopping server pipeline\n");
gst_element_set_state (pipe, GST_STATE_NULL);
gst_object_unref (pipe);
g_main_loop_unref (loop);
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