<font style="font-family: verdana,sans-serif;" size="2">Im trying to do a rtp stream sending data and another side receiving the data, the part that sends the data is working fine, but the part that receives is giving me a lot of trouble. At <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-plugins/html/gst-plugins-bad-plugins-gstrtpbin.html">http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-plugins/html/gst-plugins-bad-plugins-gstrtpbin.html</a> i have read:<br>
<br>"To use <a class="link" href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-plugins/html/gst-plugins-bad-plugins-gstrtpbin.html#GstRtpBin"><span class="type">GstRtpBin</span></a> as an RTP receiver, request a recv_rtp_sink_%<code class="literal">d</code> pad. The session
number must be specified in the pad name.
Data received on the recv_rtp_sink_%<code class="literal">d</code> pad will be processed in the gstrtpsession
manager and after being validated forwarded on <span class="type">GstRtpsSrcDemux</span> element. Each
RTP stream is demuxed based on the SSRC and send to a <a class="link" href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-plugins/html/gst-plugins-bad-plugins-gstrtpjitterbuffer.html#GstRtpJitterBuffer"><span class="type">GstRtpJitterBuffer</span></a>. After
the packets are released from the jitterbuffer, they will be forwarded to a
<span class="type">GstRtpsSrcDemux</span> element. The <span class="type">GstRtpsSrcDemux</span> element will demux the packets based
on the payload type and will create a unique pad recv_rtp_src_%<code class="literal">d_</code>%<code class="literal">d_</code>%<code class="literal">d</code> on
gstrtpbin with the session number, SSRC and payload type respectively as the pad
name.
"<br><br>on my application i cant get the recv_rtp_src_%<code class="literal">d_</code>%<code class="literal">d_</code>%<code class="literal">d, </code>i already tried on a lot of ways, my last shot was try to iterate over all the pads on the bin and try to conect, i discovered that the src pad never shows up. No error is given. I can get the on-new-ssrc signal...and other signals as <code style="font-family: verdana,sans-serif;" class="literal">on-ssrc-validated... but on all this signals the </code><span style="font-family: verdana,sans-serif;"> recv_rtp_src_%</span><code style="font-family: verdana,sans-serif;" class="literal">d_</code><span style="font-family: verdana,sans-serif;">%</span><code style="font-family: verdana,sans-serif;" class="literal">d_</code><span style="font-family: verdana,sans-serif;">%</span><code style="font-family: verdana,sans-serif;" class="literal">d is not created yet, i also tried to get the "on-pad-added" signal but this signal never happens</code></font>.<br>
<br>My problem is, when the <font style="font-family: verdana,sans-serif;" size="2"><span style="font-family: verdana,sans-serif;">recv_rtp_src_%</span><code style="font-family: verdana,sans-serif;" class="literal">d_</code><span style="font-family: verdana,sans-serif;">%</span><code style="font-family: verdana,sans-serif;" class="literal">d_</code><span style="font-family: verdana,sans-serif;">%</span><code style="font-family: verdana,sans-serif;" class="literal">d is created</code></font>. When i iterate over the pads i always get a <br>
** (teste_rtp:9516): DEBUG: GstRtpBin has [0] src pads<br><br>here goes the source code, is a little messy because im all day trying a lot of different ways to do this. And i get no error message.<br style="font-family: verdana,sans-serif;">
<span style="font-family: verdana,sans-serif;"><br>#include <gst/gst.h><br>#include <glib.h><br><br>#define PORTA_UDP_ENTRADA 5000<br><br>static gboolean<br>bus_call (GstBus *bus,<br> GstMessage *msg,<br>
gpointer data)<br>{<br> GMainLoop *loop = (GMainLoop *) data;<br><br> switch (GST_MESSAGE_TYPE (msg)) {<br><br> case GST_MESSAGE_EOS:<br> g_print ("End of stream\n");<br> g_main_loop_quit (loop);<br>
break;<br><br> case GST_MESSAGE_ERROR: {<br> gchar *debug;<br> GError *error;<br><br> gst_message_parse_error (msg, &error, &debug);<br> g_free (debug);<br><br> g_printerr ("Error: %s\n", error->message);<br>
g_error_free (error);<br><br> g_main_loop_quit (loop);<br> break;<br> }<br> default:<br> g_print("Tipo da mensagem [%d], Nome da mensagem [%s]\n", GST_MESSAGE_TYPE (msg), GST_MESSAGE_TYPE_NAME(msg));<br>
break;<br> }<br><br> return TRUE;<br>}<br><br><br>static void<br>on_new_ssrc (GstElement* gstrtpbin,<br> guint session,<br> guint ssrc,<br> gpointer data)<br>{<br>
GstPad* sinkpad;<br> GstPad* srcpad[1];<br> GstElement* decoder = (GstElement *) data;<br> GstIterator* iter;<br> gint done, linked, iter_count;<br><br> g_print ("New session stabilished, linking gstrtpbin session src pad to the rtp_decoder\n");<br>
<br> sinkpad = gst_element_get_static_pad(decoder, "sink");<br> // TODO Esta dificil de pegar o pad src do gstrtpbin que eh criado ao iniciar uma sessao nova.<br> if(!sinkpad){<br> g_warning("Error getting rtp_decoder sink pad");<br>
return;<br> }<br> /* <br> unique pad recv_rtp_src_%d_%d_%d on gstrtpbin with the session number, SSRC and payload type respectively as the pad name.<br> <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-plugins/html/gst-plugins-bad-plugins-gstrtpbin.html">http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-plugins/html/gst-plugins-bad-plugins-gstrtpbin.html</a><br>
*/<br> <br> iter = gst_element_iterate_src_pads(gstrtpbin);<br> if(!iter){<br> g_warning("Error getting gstrtpbin pads iterator");<br> return;<br> }<br><br> done = FALSE;<br> linked = FALSE;<br>
iter_count = 0;<br><br> while (!done) {<br> switch (gst_iterator_next (iter, (gpointer *) srcpad)) {<br> case GST_ITERATOR_OK:<br> if(gst_pad_link (*srcpad, sinkpad) != GST_PAD_LINK_OK){<br> g_warning("Error linking gstrtpbin pad[%s] to rtp_decoder pad[%s]", gst_pad_get_name(*srcpad), gst_pad_get_name(sinkpad));<br>
}else{<br> g_warning("Linked gstrtpbin pad[%s] to rtp_decoder pad[%s] with success", gst_pad_get_name(*srcpad), gst_pad_get_name(sinkpad));<br> linked = TRUE;<br> }<br>
iter_count++;<br> gst_object_unref (*srcpad);<br> break;<br> case GST_ITERATOR_RESYNC:<br> gst_iterator_resync (iter);<br> break;<br> case GST_ITERATOR_ERROR:<br>
done = TRUE;<br> break;<br> case GST_ITERATOR_DONE:<br> done = TRUE;<br> break;<br> }<br> }<br> if(!linked){<br> g_warning("failed to found a valid recv_src_pad on gstrtpbin");<br>
}<br> g_debug("GstRtpBin has [%d] src pads", iter_count);<br><br> gst_iterator_free (iter);<br> gst_object_unref (sinkpad);<br>}<br><br>static void<br>on_pad_added (GstElement *element,<br> GstPad *pad,<br>
gpointer data)<br>{<br> GstPad *sinkpad;<br> GstElement *decoder = (GstElement *) data;<br><br> /* We can now link this pad with the converter sink pad */<br> g_print ("Dynamic pad created, linking wavparser/converter\n");<br>
<br> sinkpad = gst_element_get_static_pad (decoder, "sink");<br> if(gst_pad_link (pad, sinkpad) != GST_PAD_LINK_OK){<br> g_warning("Error linking recv_rtp_src pad to sinkpad");<br> }<br> gst_object_unref (sinkpad);<br>
}<br><br>int<br>main (int argc,<br> char *argv[])<br>{<br> GMainLoop *loop;<br><br> GstElement *pipeline, *source, *rtp_bin, *rtp_decoder, *sink;<br> GstPad *gstrtp_sink_pad;<br> GstBus *bus;<br><br> /* Initialisation */<br>
gst_init (&argc, &argv);<br><br> loop = g_main_loop_new (NULL, FALSE);<br><br> /* Create gstreamer elements */<br> pipeline = gst_pipeline_new ("audio-player");<br> source = gst_element_factory_make ("udpsrc","udp-source");<br>
rtp_bin = gst_element_factory_make ("gstrtpbin", "gst_rtpbin");<br> rtp_decoder = gst_element_factory_make ("rtpL16depay", "rtp_decoder");<br> sink = gst_element_factory_make ("filesink", "file-sink");<br>
<br> if (!pipeline || !source || !sink || !rtp_decoder || !rtp_bin) {<br> g_printerr ("One element could not be created. Exiting.\n");<br> return -1;<br> }<br><br> gstrtp_sink_pad = gst_element_get_request_pad(rtp_bin, "recv_rtp_sink_0");<br>
if (!gstrtp_sink_pad) {<br> g_printerr ("Sink pad could not be created. Exiting.\n");<br> return -1;<br> }<br> <br> /* Set up the pipeline */<br> g_object_set (G_OBJECT (source), "port", PORTA_UDP_ENTRADA , NULL);<br>
g_object_set (G_OBJECT (sink), "location", "dados_recebidos_rtp" , NULL);<br><br> /* we add a message handler */<br> bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));<br> gst_bus_add_watch (bus, bus_call, loop);<br>
gst_object_unref (bus);<br><br> /* we add all elements into the pipeline */<br> /* file-source | ogg-demuxer | vorbis-decoder | converter | alsa-output */<br> gst_bin_add_many (GST_BIN (pipeline),<br> source, sink, rtp_bin, rtp_decoder, NULL);<br>
<br> /* we link the elements together */<br> if(gst_pad_link(gst_element_get_static_pad(source, "src"), gstrtp_sink_pad) != GST_PAD_LINK_OK){<br> g_warning("Error linking source to the gstrtp_sink_pad");<br>
gst_object_unref (GST_OBJECT (pipeline));<br> return 0;<br> }<br> <br> /* <br> After the packets are released from the jitterbuffer, they will be forwarded to a GstRtpsSrcDemux element.<br> The GstRtpsSrcDemux element will demux the packets based on the payload type and will create a unique pad <br>
recv_rtp_src_%d_%d_%d on gstrtpbin with the session number, SSRC and payload type respectively as the pad name.<br> Because of that we have to dinamicaly link the src pads on runtime. <br> */<br> g_signal_connect (rtp_bin, "pad-added", G_CALLBACK (on_pad_added), rtp_decoder);<br>
g_signal_connect (rtp_bin, "on-new-ssrc", G_CALLBACK (on_new_ssrc), rtp_decoder);<br><br> if(!gst_element_link (rtp_decoder, sink)){<br> g_warning("Error linking the rtp_decoder to the sink");<br>
gst_object_unref (GST_OBJECT (pipeline));<br> return -1;<br> }<br><br> /* Set the pipeline to "playing" state*/<br> g_print ("listening on port: %d\n", PORTA_UDP_ENTRADA);<br> gst_element_set_state (pipeline, GST_STATE_PLAYING);<br>
<br> /* Iterate */<br> g_print ("Running...\n");<br> g_main_loop_run (loop);<br><br> /* Out of the main loop, clean up nicely */<br> g_print ("Returned, stopping listening on port\n");<br> gst_element_set_state (pipeline, GST_STATE_NULL);<br>
<br> g_print ("Deleting pipeline\n");<br> gst_object_unref (GST_OBJECT (pipeline));<br><br> return 0;<br>}<br><br></span>