All pastes #1885278 Raw Edit

Unnamed

public text v1 · immutable
#1885278 ·published 2010-06-17 19:14 UTC
rendered paste body
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gst/gst.h>

static GstElement *pipeline, *adder;
static GMainLoop *loop;
static GstElement *newsrc;
static GstElement *newaudio_decoder, *newconvert;
static GstPad *newsinkpad, *newsrcpad, *probepad;
guint handler;

static void remove_source ();
static void add_source (char *file_location);

static 
gboolean eos_message_received_element (GstObject * pad, GstEvent * event, gpointer data)
{
  if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
    g_print ("EOS\n");
    g_print ("\n");
    remove_source ();
    add_source ("test.mp3");
  }
  return TRUE;
}

/* dynamically add the source to the pipeline and link it to a new pad on
 * adder */
static void
add_source (char *file_location)
{
  /* make source with unique name */
  newsrc = gst_element_factory_make ("filesrc", "filesrc1");
  g_object_set (newsrc, "location", file_location, NULL);
  newaudio_decoder = gst_element_factory_make ("mad", "mad2"); 
  newconvert = gst_element_factory_make ("audioconvert", "convert1");

  /* add to the bin */
  gst_bin_add_many (GST_BIN (pipeline), newsrc, newaudio_decoder, newconvert, NULL);

  gst_element_link_many (newsrc, newaudio_decoder, newconvert, NULL);

  probepad = gst_element_get_static_pad (newsrc, "src");
  handler = gst_pad_add_event_probe (probepad, G_CALLBACK(eos_message_received_element), NULL);
  /* get pad from the element */
  newsrcpad = gst_element_get_static_pad (newconvert, "src");

  /* get new pad from adder, adder will now wait for data on this pad */
  newsinkpad = gst_element_get_request_pad (adder, "sink%d");

  /* link pad to adder */
  gst_pad_link (newsrcpad, newsinkpad);

  /* and play the element */
  gst_element_set_state (newsrc, GST_STATE_PLAYING);
  gst_element_set_state (newaudio_decoder, GST_STATE_PLAYING);
  gst_element_set_state (newconvert, GST_STATE_PLAYING);

}

/* remove the source from the pipeline after removing it from adder */
static void
remove_source ()
{
  gst_pad_unlink (newsrcpad, newsinkpad);
  gst_element_set_state (newsrc, GST_STATE_NULL);
  gst_element_set_state (newaudio_decoder, GST_STATE_NULL);
  gst_element_set_state (newconvert, GST_STATE_NULL);

  /* unlink from adder */
//  gst_pad_unlink (newsrcpad, newsinkpad);
  gst_pad_remove_event_probe (probepad, handler);
  gst_object_unref (newsrcpad);

  /* remove from the bin */
  gst_bin_remove_many (GST_BIN (pipeline), newsrc, newaudio_decoder, newconvert, NULL);

  /* give back the pad */
  gst_element_release_request_pad (adder, newsinkpad);
  gst_object_unref (newsinkpad);
  gst_object_unref (probepad);
  gst_object_unref (newsrc);
  gst_object_unref (newaudio_decoder);
  gst_object_unref (newconvert);

}

static void
message_received (GstBus * bus, GstMessage * message, GstPipeline * pipeline)
{
  const GstStructure *s;

  s = gst_message_get_structure (message);
  g_print ("message from \"%s\" (%s): ",
      GST_STR_NULL (GST_ELEMENT_NAME (GST_MESSAGE_SRC (message))),
      gst_message_type_get_name (GST_MESSAGE_TYPE (message)));
  if (s) {
    gchar *sstr;

    sstr = gst_structure_to_string (s);
    g_print ("%s\n", sstr);
    g_free (sstr);
  } else {
    g_print ("no message details\n");
  }
}

static void
eos_message_received (GstBus * bus, GstMessage * message,
    GstPipeline * pipeline)
{
  message_received (bus, message, pipeline);
  g_main_loop_quit (loop);
}

int
main (int argc, char *argv[])
{
  GstBus *bus;
  GstElement *filter, *convert, *convert1,  *sink, *src1, *audio_decoder;
  GstCaps *caps;
  GstPad  *srcpad;
  GstPad  *sinkpad;
  gboolean res;

  gst_init (&argc, &argv);

  loop = g_main_loop_new (NULL, TRUE);

  pipeline = gst_pipeline_new ("pipeline");

  /* add the fixed part to the pipeline. Remember that we need a capsfilter
   * after adder so that multiple sources are not racing to negotiate
   * a format */
  adder = gst_element_factory_make ("adder", "adder");
  filter = gst_element_factory_make ("capsfilter", "filter");
  convert = gst_element_factory_make ("audioconvert", "convert");
  sink = gst_element_factory_make ("pulsesink", "sink");
  g_object_set (G_OBJECT(sink), "sync", FALSE, NULL);
 

  caps = gst_caps_new_simple ("audio/x-raw-int",
      "endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
      "channels", G_TYPE_INT, 1,
      "width", G_TYPE_INT, 16,
      "depth", G_TYPE_INT, 16,
      "rate", G_TYPE_INT, 44100, "signed", G_TYPE_BOOLEAN, TRUE, NULL);
  g_object_set (filter, "caps", caps, NULL);
  gst_caps_unref (caps);

  src1 = gst_element_factory_make ("filesrc", "filesrc0");
  g_object_set (src1, "location", argv[1], NULL);

  audio_decoder = gst_element_factory_make ("mad", "mad"); 
  convert1 = gst_element_factory_make ("audioconvert", "convert2");

  gst_bin_add_many (GST_BIN (pipeline), adder, filter, convert, sink, src1, audio_decoder, convert1, NULL);

  res = gst_element_link_many (src1, audio_decoder, convert1, NULL); 
  g_assert (res);
  
  res = gst_element_link_many (adder, filter, convert, sink, NULL);
  g_assert (res);

  /* get pad from the element */
  srcpad = gst_element_get_static_pad (convert1, "src");
  /* get new pad from adder, adder will now wait for data on this pad */
  sinkpad = gst_element_get_request_pad (adder, "sink%d");
  /* link pad to adder */
  gst_pad_link (srcpad, sinkpad);

  /* setup message handling */
  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);
  g_signal_connect (bus, "message::error", (GCallback) message_received,
      pipeline);
  g_signal_connect (bus, "message::warning", (GCallback) message_received,
      pipeline);
  g_signal_connect (bus, "message::eos", (GCallback) eos_message_received,
      pipeline);

  /* we set the pipeline to PLAYING, the pipeline will not yet preroll because
   * there is no source providing data for it yet */
  gst_element_set_state (pipeline, GST_STATE_PLAYING);

  add_source ("test.mp3");
  /* go to main loop */
  g_main_loop_run (loop);

  gst_element_set_state (pipeline, GST_STATE_NULL);

  gst_object_unref (bus);
  gst_object_unref (pipeline);

  return 0;
}