Aftnix
Aftnix

Reputation: 4599

Reading "wav" files using streamer

I'm trying to implement the following pipeline in 'C':

arif@dev:~/GS_samples/cmd_GS$gst-launch-0.10 filesrc location="../sample_media/M1F1-Alaw-AFsp.wav" ! wavparse ! alawdec ! autoaudiosink

Here is the implementation which i have written

#include <gst/gst.h>

void on_pad_added(GstElement *src_element, GstPad *src_pad, gpointer data);
static gboolean bus_cb(GstBus *bus, GstMessage *message, gpointer data);

static GMainLoop *loop;

int main(int argc, char **argv) {

    GstElement *pipeline;
    GstElement *src;
    GstElement *dec;
    GstElement *parse;
    GstElement *sink;
    GstBus *bus;

    gst_init(&argc, &argv);

    loop = g_main_loop_new (NULL, FALSE);

    pipeline = gst_pipeline_new("wav_player");

    src = gst_element_factory_make("filesrc","src");
    sink = gst_element_factory_make("autoaudiosink","sink");
    parse = gst_element_factory_make("wavparse","parse");
    dec = gst_element_factory_make("alawdec", "dec");

    gst_bin_add_many (GST_BIN(pipeline), src,parse,dec,sink, NULL);
    g_object_set( G_OBJECT (src) , "location",argv[1], NULL);

    gst_element_link(src,parse);
    gst_element_link(dec,sink);
    g_signal_connect (dec, "pad-added", G_CALLBACK (on_pad_added), dec);

    bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
    gst_bus_add_watch (bus, bus_cb, NULL);
    gst_object_unref(bus);
    gst_element_set_state(pipeline, GST_STATE_PLAYING);
    g_main_loop_run(loop);
    return 0;

}

void on_pad_added (GstElement *src_element, GstPad *src_pad, gpointer data) 
{
    g_print ("linking dynamic pad ...\n");

    GstElement *sink_element = (GstElement *) data;
    GstPad *sink_pad = gst_element_get_static_pad(sink_element, "sink");
    gst_pad_link (src_pad, sink_pad);
    gst_object_unref(sink_pad);

}

static gboolean bus_cb(GstBus *bus, GstMessage *message, gpointer    data)
{
  g_print ("Got %s message\n", GST_MESSAGE_TYPE_NAME (message));

  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);
      g_error_free (err);
      g_free (debug);

      g_main_loop_quit (loop);
      break;
    }
    case GST_MESSAGE_EOS:
      /* end-of-stream */
      g_main_loop_quit (loop);
      break;
    default:
      /* unhandled message */
      break;
  }

  /* we want to be notified again the next time there is a message
   * on the bus, so returning TRUE (FALSE means we want to stop watching
   * for messages on the bus and our callback should not be called again)
   */
  return TRUE;
}

But this does not work :

arif@dev:~/GS_samples/cmd_GS$./a.out ../sample_media/M1F1-Alaw-AFsp.wav 
Got state-changed message
Got state-changed message
Got stream-status message
Got tag message
Got error message
Error: Internal data flow error.

Upvotes: 0

Views: 201

Answers (1)

fer y
fer y

Reputation: 525

The problem is in this line :

gst_element_link(src,parse);
gst_element_link(dec,sink);

You are trying to build one pipeline that does one task for you , but you are not linking them properly. You should use : gst_element_link_many(src,parse,dec,sink)

Pay attention that the order of these elements are important and the output of one, is the input of the other.

EDIT: You also have two other problems which i just modified and it is working:

  1. why are you using a decoder? you are already parsing your .wav file drop the decoder element and have the data flow to audiosink to be played.

  2. nowhere in your code are you setting your pipeline to playing State. add this block of code to set your pipe to playing state:

    GstStateChangeReturn ret; ret = gst_element_set_state (pipeline, GST_STATE_PLAYING); if (ret == GST_STATE_CHANGE_FAILURE) { g_printerr ("Unable to set the pipeline to the playing state.\n"); gst_object_unref (pipeline); return -1; }

Upvotes: 1

Related Questions