UDP Sink

Jon Lovewell jon at csoftware.co.uk
Wed Sep 4 09:06:35 PDT 2013


Hello everyone

I have encountered a problem using udpsink in windows and wonder if anyone can help.

I am not sure if the issue is down to me (as I have ported it use the current V1.0 release), or it is in fact a bug.

The problem that I have is that the udpsink is not sending any packets at all.  The code catches the following warning message being emitted from the pipeline:


WarningMessage:-          Error sending UDP packet

DebugInfo:-                       gstmultiudpsink.c(545): gst_multiudpsink_= render (): /GstPipeline:pipeline0/GstUDPSink:rtpsink:

Reason: Error sending message: The system detected an invalid pointer address in attempting to use a pointer argument in a call.

I have run the equivalent pipeline from a launch line on a virtual machine running Ubuntu V12.04 and everything works fine.  I can even connect to this stream using windows but the same message is emitted by the udpsink in this pipeline that is used for the rtcp connection.

Any help or information would be appreciated.

Kind Regards

Jon

The code that I have ported is as follows:

/*
 * A Hands-On Course in GStreamer Development
 * Copyright 2008 Wim Taymans <wim.taymans at gmail.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#include <gst/gst.h>

/*
 * A simple RTP server
 *  sends the output of alsasrc as alaw encoded RTP on port 5002, RTCP is sent on
 *  port 5003. The destination is 127.0.0.1.
 *  the receiver RTCP reports are received on port 5007
 *
 * .-------.    .-------.    .-------.      .----------.     .-------.
 * | src   |    |alawenc|    |pcmapay|      | rtpbin   |     |udpsink|  RTP
 * |      src->sink    src->sink    src->send_rtp send_rtp->sink     | port=5002
 * '-------'    '-------'    '-------'      |          |     '-------'
 *                                          |          |
 *                                          |          |     .-------.
 *                                          |          |     |udpsink|  RTCP
 *                                          |    send_rtcp->sink     | port=5003
 *                           .-------.      |          |     '-------' sync=false
 *                RTCP       |udpsrc |      |          |               async=false
 *              port=5007    |     src->recv_rtcp      |
 *                           '-------'      '----------'
 */

static void
on_ssrc_active_cb (GObject *session, GObject *source, gpointer user_data)
{
  GstStructure *stats;
  gchar *str;

  /* get the source stats */
  g_object_get (source, "stats", &stats, NULL);

  /* simply dump the stats structure */
  str = gst_structure_to_string (stats);
  g_print ("source stats: %s\n", str);

  gst_structure_free (stats);
  g_free (str);
}

static void
on_sending_rtcp_cb (GObject *session, GstBuffer *buffer, gboolean early, gpointer user_data)
{
  GstMapInfo info;

  g_print ("we're sending RTCP\n");

  if(gst_buffer_map(buffer, &info, GST_MAP_READ))
  {
           gst_util_dump_mem (info.data, gst_buffer_get_size(buffer));

           gst_buffer_unmap(buffer, &info);
  }
}

int
main (int argc, char *argv[])
{
  GstElement *pipeline, *src, *enc, *pay;
  GstElement *rtpbin, *rtpsink, *rtcpsink, *rtcpsrc;
  GError *error = NULL;
  GstStateChangeReturn res;
  GstBus *bus;
  gboolean done, eres;
  GstPadLinkReturn lres;
  GstPad *srcpad, *sinkpad;
  GObject *session;
  gchar *host = "127.0.0.1";

  /* must be called first */
  gst_init (&argc, &argv);

  if(argc > 1)
  {
           host = argv[1];
  }

  g_print ("Creating pipeline\n");

  /* create the pipeline */
  /* "audiotestsrc ! alawenc ! rtppcmapay ! udpsink port=5002 host=127.0.0.1" */
  pipeline = gst_pipeline_new ("pipeline");
  g_assert (pipeline);

  src = gst_element_factory_make ("audiotestsrc", "src");
  g_assert (src);

  enc = gst_element_factory_make ("alawenc", "enc");
  g_assert (enc);

  pay = gst_element_factory_make ("rtppcmapay", "pay");
  g_assert (pay);

  /* add capture and payloading to the pipeline and link */
  gst_bin_add_many (GST_BIN (pipeline), src, enc, pay, NULL);

  eres = gst_element_link_many (src, enc, pay, NULL);
  g_assert (eres == TRUE);

  /* the rtpbin element */
  rtpbin = gst_element_factory_make ("rtpbin", "rtpbin");
  g_assert (rtpbin);

  gst_bin_add (GST_BIN (pipeline), rtpbin);

  /* the udp sinks and source we will use for RTP and RTCP */
  rtpsink = gst_element_factory_make ("udpsink", "rtpsink");
  g_assert (rtpsink);
  g_object_set (rtpsink, "port", 5002, "host", host, NULL);

  rtcpsink = gst_element_factory_make ("udpsink", "rtcpsink");
  g_assert (rtcpsink);
  g_object_set (rtcpsink, "port", 5003, "host", host, NULL);
  /* no need for synchronisation or preroll on the RTCP sink */
  g_object_set (rtcpsink, "async", FALSE, "sync", FALSE, NULL);

  rtcpsrc = gst_element_factory_make ("udpsrc", "rtcpsrc");
  g_assert (rtcpsrc);
  g_object_set (rtcpsrc, "port", 5007, NULL);

  gst_bin_add_many (GST_BIN (pipeline), rtpsink, rtcpsink, rtcpsrc, NULL);

  /* now link all to the rtpbin, start by getting an RTP sinkpad for session 0 */
  sinkpad = gst_element_get_request_pad (rtpbin, "send_rtp_sink_0");
  srcpad = gst_element_get_static_pad (pay, "src");
  lres = gst_pad_link (srcpad, sinkpad);
  g_assert (lres == GST_PAD_LINK_OK);
  gst_object_unref (srcpad);

  /* get the RTP srcpad that was created when we requested the sinkpad above and
   * link it to the rtpsink sinkpad*/
  srcpad = gst_element_get_static_pad (rtpbin, "send_rtp_src_0");
  sinkpad = gst_element_get_static_pad (rtpsink, "sink");
  lres = gst_pad_link (srcpad, sinkpad);
  g_assert (lres == GST_PAD_LINK_OK);
  gst_object_unref (srcpad);
  gst_object_unref (sinkpad);

  /* get an RTCP srcpad for sending RTCP to the receiver */
  srcpad = gst_element_get_request_pad (rtpbin, "send_rtcp_src_0");
  sinkpad = gst_element_get_static_pad (rtcpsink, "sink");
  lres = gst_pad_link (srcpad, sinkpad);
  g_assert (lres == GST_PAD_LINK_OK);
  gst_object_unref (sinkpad);

  /* we also want to receive RTCP, request an RTCP sinkpad for session 0 and
   * link it to the srcpad of the udpsrc for RTCP */
  srcpad = gst_element_get_static_pad (rtcpsrc, "src");
  sinkpad = gst_element_get_request_pad (rtpbin, "recv_rtcp_sink_0");
  lres = gst_pad_link (srcpad, sinkpad);
  g_assert (lres == GST_PAD_LINK_OK);
  gst_object_unref (srcpad);

  g_print ("Starting playback until EOS\n");

  /* start playing */
  res = gst_element_set_state (pipeline, GST_STATE_PLAYING);
  if (res == GST_STATE_CHANGE_FAILURE) {
         g_print ("An error occured\n");
         //return -1;
  }

  GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS(GST_BIN(pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "RTP Server", NULL);


  /* wait for EOS on the bus here */
  /* get the bus from the pipeline */
  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));

  /* setup callback for activity */
  g_signal_emit_by_name (rtpbin, "get-internal-session", 0, &session);
  g_signal_connect (session, "on-ssrc-active", (GCallback) on_ssrc_active_cb,
           NULL);

  /* we're going to loop here until we get the EOS message */
  done = FALSE;
  while (!done) {
         GstMessage *message;

         message = gst_bus_timed_pop (bus, -1);

         switch (GST_MESSAGE_TYPE (message)) {
           case GST_MESSAGE_ERROR:
                   {
                          GError *err;
                          gchar *debug;

                          gst_message_parse_error (message, &err, &debug);
                          g_print ("Error: %s\n", err->message);
                          if (debug != NULL)
                          {
                                   g_printerr ("Additional debug info:\n%s\n", debug);
                          }
                          g_error_free (err);
                          g_free (debug);
                          done = TRUE;
                          break;
                   }
           case GST_MESSAGE_WARNING:
                   {
                          GError *err;
                          gchar *debug;

                          gst_message_parse_warning (message, &err, &debug);
                          g_print ("Warning: %s\n", err->message);
                          if (debug != NULL)
                          {
                                   g_printerr ("Additional debug info:\n%s\n", debug);
                          }
                          g_error_free (err);
                          g_free (debug);
                          break;
                   }
           case GST_MESSAGE_EOS:
                 g_print ("got EOS!\n");
                 done = TRUE;
                 break;
           default:
                 /* don't really care about other messages */
                   g_print("Unhandled %s Message.\n", GST_MESSAGE_TYPE_NAME(message));
                 break;
         }
         gst_message_unref (message);
  }

  gst_object_unref (bus);

  g_print ("Ending playback and stopping pipeline\n");

  /* stop the pipeline */
  gst_element_set_state (pipeline, GST_STATE_NULL);

  /* Unreffing the pipeline will clean up all its children too */
  gst_object_unref (pipeline);

  return 0;
}


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/gstreamer-devel/attachments/20130904/4c30c368/attachment-0001.html>


More information about the gstreamer-devel mailing list