Hi Philippe,

Ok, I've done some more debugging and what I found was that when I attached a 
source to the rtpbin 'sink' pad after the rtpbin had been set to PLAYING, the 
gst_rtp_bin_setup_send_elements function would never get called and no data 
would hit the network.  I also discovered that the reverse issue also exists; 
if a sink is attached to the rtpbin 'src' pad after setting rtpbin to 
PLAYING, it will not be able to receive any data from the network.  I have 
attached another test program that demonstrates this second case.

The reason for these two problems is that when rtpbin changes state from NULL 
to READY, it checks to see if at least one of the source or sink request pads 
were created before calling gst_rtp_bin_setup_elements.  If only one of the 
pads was created, than only one of send or recv elements will be created and 
initialized.  If at a later point in time, an element is linked to the 
previously unlinked pad on rtpbin, a request pad will be created in  
gst_rtp_bin_request_new_pad however the underlying elements that should read 
or write to these pads do not exist!

I have attached a patch for rtpbin that will create these elements when the 
request pads are created if necessary.  I don't know if this is the best way 
to solve the problem but maybe it will give you a hint for better way if it 
exists.  So far with my own testing the patch seems to be ok as is.

If you compile and run my two test programs without my patch, you should see 
that the payload type callbacks are only reached when using a fake source or 
sink, eg.
./rtpbinfakesinktest --use-fakesink
./rtpbinfakesinktest
./rtpbinfakesrctest --use-fakesrc
./rtpbinfakesrctest

With my patch, the callbacks are reached in all cases.

Regards,
~Scott


On Thursday 11 January 2007 10:24, Philippe Khalaf wrote:
> Hi,
>
> I don't really have time to look at your stuff but you should do some
> basic gstreamer debugging. Run your program with :
> GST_DEBUG="rtpbin:5, rtpsend:5, rtprecv:5" and look for any suspicious
> messages.
>
> Regards,
> Philippe
>
> On Wed, 10 Jan 2007 00:22:03 -0700
>
> Scott Zuk <[EMAIL PROTECTED]> wrote:
> > Hi,
> >
> > I'm trying to use the rtpbin element in a pipeline that I want to set up
> > initially to receive rtp data but change to send and receive when a
> > destination and send codec is known.  I have attached a small test
> > program that shows what I am doing.
> >
> > Basically, I create a pipeline and add rtpbin and rtpdemux elements and
> > set the pipeline to playing to start receiving data.  After a few seconds
> > I add an audio source, encoder and payloader to the pipeline, link them
> > up and set a destination ip and port.  The problem though is that no rtp
> > data ever gets to the network and hence the rtp payload callbacks are
> > never called (I'm sending to the listen port).  Not sure why this is
> > happening.
> >
> > However, if I add a fakesrc element to the pipeline and link it to the
> > sink pad of the rtpbin and remove it immediately after setting the
> > pipeline to playing, sending rtp audio will then be successful.  It seems
> > like a hack to me though.  You can activate this behavior in my test
> > program by passing the --use-fakesrc argument.  It seems that linking the
> > fakesrc to the rtpbin sink causes something to be initialized differently
> > but I don't know what. Any ideas?
> >
> > BTW, I'm using a copy of the latest rtpbin from darcs compiled without
> > jrtp and jingle and gstreamer 0.10.10
> >
> > Thanks,
> > ~Scott
>
> -------------------------------------------------------------------------
> Take Surveys. Earn Cash. Influence the Future of IT
> Join SourceForge.net's Techsay panel and you'll get the chance to share
> your opinions on IT & business topics through brief surveys - and earn cash
> http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
> _______________________________________________
> Farsight-devel mailing list
> Farsight-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/farsight-devel
#include <stdio.h>
#include <glib.h>
#include <gst/gst.h>
#include <unistd.h>
#include <assert.h>

void gstNewPayloadType(GstElement *element, gint pt, GstPad *pad, gpointer data)
{
    printf("Received new RTP payload type %d\n", pt);
}

void gstPayloadTypeChange(GstElement *element, gint pt, gpointer data)
{
    printf("RTP payload type changed to %d\n", pt);
}

// send first
int main(int argc, char *argv[])
{
    gboolean use_fakesink = FALSE;

    gst_init(NULL, NULL);

    if (argc == 2)
    {
        if (g_ascii_strncasecmp(argv[1], "--use-fakesink", 14) == 0)
        {
            printf("Using fakesink\n");
            use_fakesink = TRUE;
        }
    }

    GstElement *pipeline = gst_pipeline_new("pipeline");
    GstElement *rtpBin = gst_element_factory_make("rtpbin", NULL);
    GstElement *rtpDemux = gst_element_factory_make("rtpdemux", NULL);
    GstElement *fakeSink = NULL;
    GstElement *audioSrc = gst_element_factory_make("audiotestsrc", NULL);
    GstElement *audioEncoder = gst_element_factory_make("mulawenc", NULL);
    GstElement *audioPayloader = gst_element_factory_make("rtppcmupay", NULL);

    gst_bin_add_many(GST_BIN(pipeline), rtpBin, audioSrc, audioEncoder, audioPayloader, NULL);

    assert(gst_element_link(audioPayloader, rtpBin) == TRUE);
    assert(gst_element_link(audioEncoder, audioPayloader) == TRUE);
    assert(gst_element_link(audioSrc, audioEncoder) == TRUE);

    g_object_set(G_OBJECT(audioSrc), "is-live", TRUE, NULL);
    g_object_set(G_OBJECT(audioSrc), "blocksize", 320, NULL);
    g_object_set(G_OBJECT(audioPayloader), "max_ptime", G_GINT64_CONSTANT(20000000), NULL);
    g_object_set(G_OBJECT(rtpBin), "destinations", "127.0.0.1:6660", NULL);
    g_object_set(G_OBJECT(rtpBin), "rtcp-support", FALSE, "localport", 6660, NULL);

    if (use_fakesink)
    {
        fakeSink = gst_element_factory_make("fakesink", NULL);
        gst_bin_add(GST_BIN(pipeline), fakeSink);
        assert(gst_element_link_pads(rtpBin, "src%d", fakeSink, "sink") == TRUE);
    }

    gst_element_set_state(pipeline, GST_STATE_PLAYING);
    
    if (use_fakesink)
    {
        gst_bin_remove(GST_BIN(pipeline), fakeSink);
    }
    
    printf("\nStarting to send...\n");
    for (int i = 0; i < 5; ++i)
    {
        printf(".");
        fflush(NULL);
        sleep(1);
    }

    gst_bin_add(GST_BIN(pipeline), rtpDemux);
    assert(gst_element_link(rtpBin, rtpDemux) == TRUE);

    g_signal_connect(G_OBJECT(rtpDemux), "new-payload-type", G_CALLBACK(gstNewPayloadType), NULL);
    g_signal_connect(G_OBJECT(rtpDemux), "payload-type-change", G_CALLBACK(gstPayloadTypeChange), NULL);

    gst_element_set_state(rtpDemux, GST_STATE_PLAYING);

    printf("Starting to receive...\n");
    for (int i = 0; i < 5; ++i)
    {
        printf(".");
        fflush(NULL);
        sleep(1);
    }

    printf("\ndone.\n");
    return 0;
}
diff -rN -u old-gst-plugins-farsight/ext/jrtp/gstrtpbin.c new-gst-plugins-farsight/ext/jrtp/gstrtpbin.c
--- old-gst-plugins-farsight/ext/jrtp/gstrtpbin.c	2007-01-12 23:06:03.000000000 -0700
+++ new-gst-plugins-farsight/ext/jrtp/gstrtpbin.c	2007-01-12 23:06:03.000000000 -0700
@@ -386,6 +386,21 @@
                 goto error;
             }
 
+            /* Setup send elements if this pad was added after changing
+               to the READY state. */
+            if (GST_STATE(rtp_bin) >= GST_STATE_READY)
+            {
+                if (!rtp_bin->bypass_udp)
+                {
+                    if (!gst_rtp_bin_setup_send_elements(rtp_bin)) {
+                        goto error;
+                    }
+                    /* Set children to the same state as parent so they
+                       start running if rtpbin is already in PLAYING state. */
+                    gst_element_sync_state_with_parent(rtp_bin->rtpsink);
+                }
+            }
+
             break;
 
         case GST_PAD_SRC:          /* Create rtprecv and its ghost pad. */
@@ -421,6 +436,22 @@
                 goto error;
             }
 
+            /* Setup recv elements if this pad was added after changing
+               to the READY state. */
+            if (GST_STATE(rtp_bin) >= GST_STATE_READY)
+            {
+                if (!rtp_bin->bypass_udp)
+                {
+                    if (!gst_rtp_bin_setup_recv_elements(rtp_bin)) {
+                        goto error;
+                    }
+                    /* Set children to the same state as parent so they
+                       start running if rtpbin is already in PLAYING state. */
+                    gst_element_sync_state_with_parent(rtp_bin->rtpsrc);
+                    gst_element_sync_state_with_parent(rtp_bin->jbuf);
+                }
+            }
+
             break;
 
         default:
@@ -577,7 +608,7 @@
     jrtpsession_setpads (rtp_bin->sess, rtp_src_pad, rtcp_src_pad);
 #endif
 
-    GST_DEBUG("Elements setup propertly");
+    GST_DEBUG("Elements setup properly");
     return TRUE;
 }
 
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Farsight-devel mailing list
Farsight-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/farsight-devel

Reply via email to