[gst-devel] Problem using appsink on simple example

Tiago Katcipis katcipis at inf.ufsc.br
Wed Jul 8 16:25:21 CEST 2009


Im going to use appsink on a project using gstreamer and started to build a
basic example os]f how to use appsink using signals. My problem is that when
i simply add the appsink to the pipeline, the pipe simply stops to work.

On the following example im just trying to use the appsink instead the
filesink to write the entire stream to a file. If i use the filesink and
DONT add the appsink to the pipe, it works fine, if i just add the appsink
to the pipe ....it stops working, im not even using the appsink yet, the
filesink stops to write data, the result of the test will be an empty file,
and no error msg is sent. I dont know what detail im missing on how to use
appsink, hope someone can help me. By the way, gst_bin_add returns TRUE when
i add the appsink.

the source code of the example:

#include <gst/gst.h>
#include <glib.h>
#include <gst/app/gstappsink.h>
#include <stdio.h>

static gboolean
bus_call (GstBus     *bus,
          GstMessage *msg,
          gpointer    data)
{
  GMainLoop *loop = (GMainLoop *) data;

  switch (GST_MESSAGE_TYPE (msg)) {

    case GST_MESSAGE_EOS:
      g_print ("End of stream\n");
      g_main_loop_quit (loop);
      break;

    case GST_MESSAGE_ERROR: {
      gchar  *debug;
      GError *error;

      gst_message_parse_error (msg, &error, &debug);
      g_free (debug);

      g_printerr ("Error: %s\n", error->message);
      g_error_free (error);

      g_main_loop_quit (loop);
      break;
    }
    default:
      g_print("Msg type[%d], Msg type name[%s]\n", GST_MESSAGE_TYPE(msg),
GST_MESSAGE_TYPE_NAME(msg));
      break;
  }

  return TRUE;
}


static void link_two_elements(GstElement* src_element, GstElement*
sink_element)
{
  if(!gst_element_link(src_element, sink_element))
      g_debug("Error linking %s to %s", gst_element_get_name(src_element),
gst_element_get_name(sink_element));

}

static void link_two_pads(GstPad* src_pad, GstPad* sink_pad)
{
  if(!src_pad){
      g_warning("Error: src_pad is NULL on link_two_pads");
      return;
  }

  if(!sink_pad){
      g_warning("Error: sink_pad is NULL on link_two_pads");
      return;
  }

  if(gst_pad_link(src_pad, sink_pad) != GST_PAD_LINK_OK)
      g_debug("Error linking pads %s to %s", gst_pad_get_name(src_pad),
gst_pad_get_name(sink_pad));

}

static void on_new_buffer (GstElement* object,
                           gpointer user_data)
{
  FILE* file = (FILE*) user_data;
  GstAppSink* app_sink = (GstAppSink*) object;
  GstBuffer * buffer = gst_app_sink_pull_buffer(app_sink);

  if(fwrite (GST_BUFFER_DATA(buffer), 1 , GST_BUFFER_SIZE(buffer) , file) !=
GST_BUFFER_SIZE(buffer)){
      g_debug("Error writing data from appsink to file!!!");
  }else{
      g_debug("Data pulled from appsink and writed to file with success!!");
  }

}

// Pipe to test this src: gst-launch audiotestsrc ! audioconvert ! alawenc !
rtppcmapay ! udpsink host=127.0.0.1 port=5000
// Equivalent working pipe: gst-launch udpsrc port=5000
caps=application/x-rtp ! gstrtpjitterbuffer ! rtppcmadepay ! alawdec !
audioconvert ! lame ! appsink
int
main (int   argc,
      char *argv[])
{
  GMainLoop *loop;

  GstElement *pipeline, *source, *rtp_jitter, *rtp_alaw_depay,
             *alaw_decoder, *audio_convert, *lame, *filesink, *appsink;
  GstBus* bus;
  GstCaps* udp_caps;
  FILE* appsink_file;
  int udp_port;

  if(argc < 2){
      g_warning("Usage: %s [port_to_be_listened]", argv[0]);
      return -1;
  }

  udp_port = atoi(argv[1]);

  /* Initialisation */
  gst_init (&argc, &argv);

  udp_caps = gst_caps_from_string("application/x-rtp");
  if(!udp_caps){
      g_warning("Error alocating the udp caps");
      return -1;
  }

  loop = g_main_loop_new (NULL, FALSE);

  /* Create gstreamer elements */
  pipeline      = gst_pipeline_new("rtp-mp3-stream-decoder");
  source        = gst_element_factory_make("udpsrc",  "udp-rtp-source");
  rtp_jitter     = gst_element_factory_make("gstrtpjitterbuffer",
"rtp-jitter-buffer");
  rtp_alaw_depay = gst_element_factory_make("rtppcmadepay",
"rtp_alaw_depay");
  alaw_decoder   = gst_element_factory_make("alawdec","alaw-decoder");
  audio_convert  = gst_element_factory_make("audioconvert","audio-convert");
  lame           = gst_element_factory_make("lame","mp3-encoder");
  filesink       = gst_element_factory_make("filesink", "file-mp3-output");
  appsink        = gst_element_factory_make("appsink", "sink-buffer");


  if (!pipeline || !source || !rtp_jitter || !appsink ||
      !rtp_alaw_depay || !alaw_decoder || !audio_convert || !lame ||
!filesink) {
      g_printerr ("Elements could not be created. Exiting.\n");
      return -1;
  }

  appsink_file = fopen("received_audio_appsink.mp3", "w");
  if(!appsink_file){
      g_printerr ("Appsink file could not be created. Exiting.\n");
      return -1;
  }

  /* Set up the pipeline */

  /* we set the properties to the source element to receive only rtp
packets*/
  g_object_set(G_OBJECT (source), "port", udp_port, NULL);
  g_object_set(G_OBJECT (source), "caps", udp_caps, NULL);
  /* we set the location of the mp3 generated file */
  g_object_set(G_OBJECT (filesink), "location",
"received_audio_filesink.mp3", NULL);

  /*
    Make appsink emit the "new-preroll" and "new-buffer" signals. This
option is by default disabled because
    signal emission is expensive and unneeded when the application prefers
to operate in pull mode.
  */
  gst_app_sink_set_emit_signals ((GstAppSink*) appsink, TRUE);

  /* we add a message handler */
  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  gst_bus_add_watch (bus, bus_call, loop);
  gst_object_unref (bus);

  /* we add all elements into the pipeline */
  gst_bin_add_many (GST_BIN (pipeline),
                    source, rtp_jitter, rtp_alaw_depay, alaw_decoder,
audio_convert, lame, filesink, NULL);

  /* When i just addn the appsink this the example stops to work and the
file will be empty (and im not using the appsink, just the filesink)
  if(gst_bin_add(GST_BIN (pipeline), appsink)){
      g_debug("Adcionou appsink com sucesso");
  }else{
      g_debug("Erro ao Adcionar appsink");
  }*/

  /* we link all the elements together */
  link_two_elements(source, rtp_jitter);
  link_two_elements(rtp_jitter, rtp_alaw_depay);
  link_two_elements(rtp_alaw_depay, alaw_decoder);
  link_two_elements(alaw_decoder, audio_convert);
  link_two_elements(audio_convert, lame);
  link_two_elements(lame, filesink);

  /* Conecting to the new-buffer signal emited by the appsink */
  g_signal_connect (appsink, "new-buffer",  G_CALLBACK (on_new_buffer),
appsink_file);

  /* Set the pipeline to "playing" state*/
  g_print ("Now listening on port: %d\n", udp_port);
  gst_element_set_state (pipeline, GST_STATE_PLAYING);

  /* Iterate */
  g_print ("Running...\n");
  g_main_loop_run (loop);

  /* Out of the main loop, clean up nicely */
  g_print ("Returned, stopping listening\n");
  gst_element_set_state (pipeline, GST_STATE_NULL);

  g_print ("Deleting pipeline\n");
  gst_object_unref (GST_OBJECT (pipeline));
  fclose(appsink_file);

  return 0;
}



best regards,
Katcipis
-- 
"it might be a profitable thing to learn Java, but it has no intellectual
value whatsoever" Alexander Stepanov
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/gstreamer-devel/attachments/20090708/1e47ef3b/attachment.htm>


More information about the gstreamer-devel mailing list