예제 #1
0
static void
run_main_loop_until_eos (void)
{
  GstElement *bin =
      (GstElement *) check_gobject_get_object_property (song, "bin");
  GMainLoop *main_loop = g_main_loop_new (NULL, FALSE);
  GstBus *bus = gst_element_get_bus (bin);
  gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);
  g_signal_connect (bus, "message::error", G_CALLBACK (message_received),
      (gpointer) main_loop);
  g_signal_connect (bus, "message::eos", G_CALLBACK (message_received),
      (gpointer) main_loop);
  gst_object_unref (bus);
  gst_object_unref (bin);
  // workaround for some muxers not accepting the seek and thus not going to eos
  // poll playback position 10 times a second
  // TODO(ensonic): fixed in 1.0?
  // basesrc elements do post EOS
  old_pos = -1;
  old_playing = FALSE;
  g_signal_connect (song, "notify::play-pos",
      G_CALLBACK (on_song_play_pos_notify), (gpointer) main_loop);
  g_signal_connect (song, "notify::is-playing",
      G_CALLBACK (on_song_is_playing_notify), (gpointer) main_loop);
  guint update_id =
      g_timeout_add_full (G_PRIORITY_HIGH, 1000 / 10, on_song_playback_update,
      NULL, NULL);

  bt_song_update_playback_position (song);
  GST_INFO ("running main_loop");
  g_main_loop_run (main_loop);
  GST_INFO ("finished main_loop");
  g_source_remove (update_id);
}
예제 #2
0
파일: gamine.c 프로젝트: btong/gamine
static void
gst_play_background (GstBus *bus, gchar *filesnd, gboolean repeat)
{
    gchar *filename;
    GstElement *pipeline;
    pipeline = gst_element_factory_make("playbin", "playbin");
    if (pipeline != NULL)
    {
        closure_t *closure = g_new (closure_t, 1);
        closure->elt = pipeline;
        closure->repeat = repeat;
        bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
        gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);
        g_signal_connect (bus, "message::eos", 
            (GCallback) eos_message_received, closure);
        gst_object_unref (bus);
        filename = g_build_filename(DATADIR, "sounds", filesnd, NULL);
        if (!g_file_test (filename, G_FILE_TEST_EXISTS))
            printf(gettext("** error: %s does not exists\n"), filename);
        else {
            filename = g_strdup_printf("file://%s", filename);
            g_object_set (G_OBJECT(pipeline), "uri", filename, NULL);
            gst_element_set_state (GST_ELEMENT(pipeline), GST_STATE_PLAYING);
        }
        g_free(filename);
    }
}
예제 #3
0
static gchar *
get_media_type (const gchar * filename)
{
  GstElement *pipeline = gst_pipeline_new ("typefind");
  GstElement *filesrc = gst_element_factory_make ("filesrc", NULL);
  GstElement *typefind = gst_element_factory_make ("typefind", NULL);
  GstElement *fakesink = gst_element_factory_make ("fakesink", NULL);

  gst_bin_add_many (GST_BIN (pipeline), filesrc, typefind, fakesink, NULL);
  gst_element_link_many (filesrc, typefind, fakesink, NULL);

  g_object_set (filesrc, "location", filename, NULL);
  g_signal_connect (typefind, "have-type", (GCallback) have_type_cb, NULL);

  GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);
  g_signal_connect (bus, "message::error",
      G_CALLBACK (typefind_message_received), (gpointer) filename);
  g_signal_connect (bus, "message::eos", G_CALLBACK (typefind_message_received),
      (gpointer) filename);
  gst_object_unref (bus);

  GST_INFO ("check media type for '%s'", filename);
  typefind_media_type = NULL;
  typefind_main_loop = g_main_loop_new (NULL, FALSE);
  gst_element_set_state (pipeline, GST_STATE_PLAYING);
  // run main loop until EOS or type found
  g_main_loop_run (typefind_main_loop);
  gst_element_set_state (pipeline, GST_STATE_NULL);
  g_main_loop_unref (typefind_main_loop);
  gst_object_unref (pipeline);
  return typefind_media_type;
}
예제 #4
0
int
main (int argc, char *argv[])
{

  GstElement *pipeline = NULL;

#ifndef GST_DISABLE_PARSE
  GError *error = NULL;
#endif
  GstElement *volume;
  GstBus *bus;

#ifdef GST_DISABLE_PARSE
  g_print ("GStreamer was built without pipeline parsing capabilities.\n");
  g_print
      ("Please rebuild GStreamer with pipeline parsing capabilities activated to use this example.\n");
  return 1;
#else
  gst_init (&argc, &argv);
  gtk_init (&argc, &argv);

  pipeline = gst_parse_launchv ((const gchar **) &argv[1], &error);
  if (error) {
    g_print ("pipeline could not be constructed: %s\n", error->message);
    g_print ("Please give a complete pipeline  with a 'volume' element.\n");
    g_print ("Example: audiotestsrc ! volume ! %s\n", DEFAULT_AUDIOSINK);
    g_error_free (error);
    return 1;
  }
#endif
  volume = gst_bin_get_by_name (GST_BIN (pipeline), "volume0");
  if (volume == NULL) {
    g_print ("Please give a pipeline with a 'volume' element in it\n");
    return 1;
  }

  /* 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);

  /* setup GUI */
  setup_gui (volume);

  /* go to main loop */
  gst_element_set_state (pipeline, GST_STATE_PLAYING);
  gtk_main ();
  gst_element_set_state (pipeline, GST_STATE_NULL);
  gst_object_unref (pipeline);

  return 0;
}
예제 #5
0
int
main (int argc, char *argv[])
{
  GstBus *bus;

  gst_init (&argc, &argv);

  loop = g_main_loop_new (NULL, TRUE);

  pipeline = gst_pipeline_new ("pipeline");

  /* 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, this will distribute a default clock and
   * start running. no preroll is needed */
  gst_element_set_state (pipeline, GST_STATE_PLAYING);

  /* get the clock now. Since we never set the pipeline to PAUSED again, the
   * clock will not change, even when we add new clock providers later.  */
  theclock = gst_element_get_clock (pipeline);

  /* start our actions while we are in the mainloop so that we can catch errors
   * and other messages. */
  g_idle_add ((GSourceFunc) perform_step, GINT_TO_POINTER (0));
  /* 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);
  gst_object_unref (theclock);

  return 0;
}
예제 #6
0
gboolean
check_run_main_loop_until_msg_or_error (BtSong * song, const gchar * msg)
{
  GstStateChangeReturn sret;
  GstState state, pending;

  GMainLoop *main_loop = g_main_loop_new (NULL, FALSE);
  GstElement *bin =
      (GstElement *) check_gobject_get_object_property (song, "bin");
  GstBus *bus = gst_element_get_bus (bin);
  gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);
  g_signal_connect (bus, "message::error", G_CALLBACK (_check_message_received),
      (gpointer) main_loop);
  g_signal_connect (bus, msg,
      G_CALLBACK (_check_message_received), (gpointer) main_loop);

  _check_run_main_loop_error = FALSE;
  sret = gst_element_get_state (bin, &state, &pending, G_GUINT64_CONSTANT (0));

  // be careful to not run this when the song already finished
  if (sret != GST_STATE_CHANGE_FAILURE) {
    GST_INFO_OBJECT (song, "running main_loop: sret=%s, state=%s/%s",
        gst_element_state_change_return_get_name (sret),
        gst_element_state_get_name (state),
        gst_element_state_get_name (pending));
    g_main_loop_run (main_loop);
  } else {
    GST_INFO_OBJECT (song, "skipping main_loop: sret=%s, state=%s/%s",
        gst_element_state_change_return_get_name (sret),
        gst_element_state_get_name (state),
        gst_element_state_get_name (pending));
  }
  gst_bus_remove_signal_watch (bus);
  g_signal_handlers_disconnect_matched (bus, G_SIGNAL_MATCH_DATA, 0, 0, NULL,
      NULL, (gpointer) main_loop);
  gst_object_unref (bus);
  gst_object_unref (bin);
  g_main_loop_unref (main_loop);
  GST_INFO_OBJECT (song, "finished main_loop");
  return sret == GST_STATE_CHANGE_FAILURE ? FALSE : !_check_run_main_loop_error;
}
예제 #7
0
파일: testegl.c 프로젝트: 01org/gst-omx
int
main (int argc, char **argv)
{
  GstBus *bus;
  GOptionContext *ctx;
  GIOChannel *io_stdin;
  GError *err = NULL;
  gboolean res;
  GOptionEntry options[] = {
    {NULL}
  };
  GThread *rthread;

  /* Clear application state */
  memset (state, 0, sizeof (*state));
  state->animate = TRUE;

  /* must initialise the threading system before using any other GLib funtion */
  if (!g_thread_supported ())
    g_thread_init (NULL);

  ctx = g_option_context_new ("[ADDITIONAL ARGUMENTS]");
  g_option_context_add_main_entries (ctx, options, NULL);
  g_option_context_add_group (ctx, gst_init_get_option_group ());
  if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
    g_print ("Error initializing: %s\n", GST_STR_NULL (err->message));
    exit (1);
  }
  g_option_context_free (ctx);

  if (argc != 2) {
    g_print ("Usage: %s <URI> or <PIPELINE-DESCRIPTION>\n", argv[0]);
    exit (1);
  }

  /* Initialize GStreamer */
  gst_init (&argc, &argv);

  /* initialize inter thread comunnication */
  init_intercom (state);

  TRACE_VC_MEMORY ("state 0");

  if (!(rthread = g_thread_new ("render", (GThreadFunc) render_func, NULL))) {
    g_print ("Render thread create failed\n");
    exit (1);
  }

  /* Initialize player */
  if (gst_uri_is_valid (argv[1])) {
    res = init_playbin_player (state, argv[1]);
  } else {
    res = init_parse_launch_player (state, argv[1]);
  }

  if (!res)
    goto done;

  /* Create a GLib Main Loop and set it to run */
  state->main_loop = g_main_loop_new (NULL, FALSE);

  /* Add a keyboard watch so we get notified of keystrokes */
  io_stdin = g_io_channel_unix_new (fileno (stdin));
  g_io_add_watch (io_stdin, G_IO_IN, (GIOFunc) handle_keyboard, state);
  g_io_channel_unref (io_stdin);

  /* *INDENT-OFF* */
  g_print ("Available commands: \n"
      "  a - Toggle animation \n"
      "  p - Pause playback \n"
      "  r - Resume playback \n"
      "  l - Query position/duration\n"
      "  f - Seek 30 seconds forward \n"
      "  b - Seek 30 seconds backward \n"
      "  q - Quit \n");
  /* *INDENT-ON* */

  /* Connect the bus handlers */
  bus = gst_element_get_bus (state->pipeline);

  gst_bus_set_sync_handler (bus, (GstBusSyncHandler) bus_sync_handler, state,
      NULL);

  gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);
  gst_bus_enable_sync_message_emission (bus);

  g_signal_connect (G_OBJECT (bus), "message::error", (GCallback) error_cb,
      state);
  g_signal_connect (G_OBJECT (bus), "message::buffering",
      (GCallback) buffering_cb, state);
  g_signal_connect (G_OBJECT (bus), "message::eos", (GCallback) eos_cb, state);
  g_signal_connect (G_OBJECT (bus), "message::qos", (GCallback) qos_cb, state);
  g_signal_connect (G_OBJECT (bus), "message::state-changed",
      (GCallback) state_changed_cb, state);
  gst_object_unref (bus);

  /* Make player start playing */
  gst_element_set_state (state->pipeline, GST_STATE_PLAYING);

  /* Start the mainloop */
  state->main_loop = g_main_loop_new (NULL, FALSE);
  g_main_loop_run (state->main_loop);

done:
  /* Release pipeline */
  if (state->pipeline) {
    gst_element_set_state (state->pipeline, GST_STATE_NULL);
    if (state->vsink) {
      gst_object_unref (state->vsink);
      state->vsink = NULL;
    }

    gst_object_unref (state->pipeline);
  }

  /* Unref the mainloop */
  if (state->main_loop) {
    g_main_loop_unref (state->main_loop);
  }

  /* Stop rendering thread */
  state->running = FALSE;
  g_thread_join (rthread);

  terminate_intercom (state);

  TRACE_VC_MEMORY ("at exit");
  return 0;
}
예제 #8
0
int
main (int argc, char *argv[])
{
  GstBus *bus;
  GstElement *filter, *convert, *sink;
  GstCaps *caps;
  gboolean res;
  SprinkleState *state;

  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 ("autoaudiosink", "sink");

  caps = gst_caps_new_simple ("audio/x-raw",
      "format", G_TYPE_STRING, "S16LE",
      "channels", G_TYPE_INT, 1, "rate", G_TYPE_INT, 44100, NULL);
  g_object_set (filter, "caps", caps, NULL);
  gst_caps_unref (caps);

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

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

  /* 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);

  /* and add the function that modifies the pipeline every 100ms */
  state = create_state ();
  g_timeout_add (100, (GSourceFunc) do_sprinkle, state);

  /* go to main loop */
  g_main_loop_run (loop);

  gst_element_set_state (pipeline, GST_STATE_NULL);

  free_state (state);
  gst_object_unref (bus);
  gst_object_unref (pipeline);

  return 0;
}
예제 #9
0
/**
 * gst_bus_add_signal_watch:
 * @bus: a #GstBus on which you want to receive the "message" signal
 *
 * Adds a bus signal watch to the default main context with the default
 * priority.
 * After calling this statement, the bus will emit the "message" signal for each
 * message posted on the bus.
 *
 * This function may be called multiple times. To clean up, the caller is
 * responsible for calling gst_bus_remove_signal_watch() as many times as this
 * function is called.
 *
 * MT safe.
 */
void
gst_bus_add_signal_watch (GstBus * bus)
{
  gst_bus_add_signal_watch_full (bus, G_PRIORITY_DEFAULT);
}
예제 #10
0
/* check if removing pads work as expected */
void test_remove_pad()
{
  GstElement *bin, *src, *adder, *sink;
  GstBus *bus;
  GstPad *pad;
  gboolean res;
  //xmlfile = "test_remove_pad";
    std_log(LOG_FILENAME_LINE, "Test Started test_remove_pad");
  GST_INFO ("preparing test");

  /* build pipeline */
  bin = gst_pipeline_new ("pipeline");
  bus = gst_element_get_bus (bin);
  gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);

  src = gst_element_factory_make ("audiotestsrc", "src");
  g_object_set (src, "num-buffers", 4, NULL);
  g_object_set (src, "wave", 4, NULL);
  adder = gst_element_factory_make ("adder", "adder");
  sink = gst_element_factory_make ("fakesink", "sink");
  gst_bin_add_many (GST_BIN (bin), src, adder, sink, NULL);

  res = gst_element_link (src, adder);
  fail_unless (res == TRUE, NULL);
  res = gst_element_link (adder, sink);
  fail_unless (res == TRUE, NULL);

  /* create an unconnected sinkpad in adder */
  pad = gst_element_get_request_pad (adder, "sink%d");
  fail_if (pad == NULL, NULL);

  main_loop = g_main_loop_new (NULL, FALSE);
  g_signal_connect (bus, "message::segment-done", (GCallback) message_received,
      bin);
  g_signal_connect (bus, "message::error", (GCallback) message_received, bin);
  g_signal_connect (bus, "message::warning", (GCallback) message_received, bin);
  g_signal_connect (bus, "message::eos", (GCallback) message_received, bin);

  GST_INFO ("starting test");

  /* prepare playing, this will not preroll as adder is waiting
   * on the unconnected sinkpad. */
  res = gst_element_set_state (bin, GST_STATE_PAUSED);
  fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);

  /* wait for completion for one second, will return ASYNC */
  res = gst_element_get_state (GST_ELEMENT (bin), NULL, NULL, GST_SECOND);
  fail_unless (res == GST_STATE_CHANGE_ASYNC, NULL);

  /* get rid of the pad now, adder should stop waiting on it and
   * continue the preroll */
  gst_element_release_request_pad (adder, pad);
  gst_object_unref (pad);

  /* wait for completion, should work now */
  res =
      gst_element_get_state (GST_ELEMENT (bin), NULL, NULL,
      GST_CLOCK_TIME_NONE);
  fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);

  /* now play all */
  res = gst_element_set_state (bin, GST_STATE_PLAYING);
  fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);

  g_main_loop_run (main_loop);

  res = gst_element_set_state (bin, GST_STATE_NULL);
  fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);

  /* cleanup */
  g_main_loop_unref (main_loop);
  gst_object_unref (G_OBJECT (bus));
  gst_object_unref (G_OBJECT (bin));
  std_log(LOG_FILENAME_LINE, "Test Successful");
    create_xml(0);
}
예제 #11
0
/* check if adding pads work as expected */
void test_add_pad()
{
  GstElement *bin, *src1, *src2, *adder, *sink;
  GstBus *bus;
  gboolean res;
  //xmlfile = "test_add_pad";
    std_log(LOG_FILENAME_LINE, "Test Started test_add_pad");
  GST_INFO ("preparing test");

  /* build pipeline */
  bin = gst_pipeline_new ("pipeline");
  bus = gst_element_get_bus (bin);
  gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);

  src1 = gst_element_factory_make ("audiotestsrc", "src1");
  g_object_set (src1, "num-buffers", 4, NULL);
  g_object_set (src1, "wave", 4, NULL); /* silence */
  src2 = gst_element_factory_make ("audiotestsrc", "src2");
  /* one buffer less, we connect with 1 buffer of delay */
  g_object_set (src2, "num-buffers", 3, NULL);
  g_object_set (src2, "wave", 4, NULL); /* silence */
  adder = gst_element_factory_make ("adder", "adder");
  sink = gst_element_factory_make ("fakesink", "sink");
  gst_bin_add_many (GST_BIN (bin), src1, adder, sink, NULL);

  res = gst_element_link (src1, adder);
  fail_unless (res == TRUE, NULL);
  res = gst_element_link (adder, sink);
  fail_unless (res == TRUE, NULL);

  main_loop = g_main_loop_new (NULL, FALSE);
  g_signal_connect (bus, "message::segment-done", (GCallback) message_received,
      bin);
  g_signal_connect (bus, "message::error", (GCallback) message_received, bin);
  g_signal_connect (bus, "message::warning", (GCallback) message_received, bin);
  g_signal_connect (bus, "message::eos", (GCallback) message_received, bin);

  GST_INFO ("starting test");

  /* prepare playing */
  res = gst_element_set_state (bin, GST_STATE_PAUSED);
  fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);

  /* wait for completion */
  res =
      gst_element_get_state (GST_ELEMENT (bin), NULL, NULL,
      GST_CLOCK_TIME_NONE);
  fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);

  /* add other element */
  gst_bin_add_many (GST_BIN (bin), src2, NULL);

  /* now link the second element */
  res = gst_element_link (src2, adder);
  fail_unless (res == TRUE, NULL);

  /* set to PAUSED as well */
  res = gst_element_set_state (src2, GST_STATE_PAUSED);

  /* now play all */
  res = gst_element_set_state (bin, GST_STATE_PLAYING);
  fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);

  g_main_loop_run (main_loop);

  res = gst_element_set_state (bin, GST_STATE_NULL);
  fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);

  /* cleanup */
  g_main_loop_unref (main_loop);
  gst_object_unref (G_OBJECT (bus));
  gst_object_unref (G_OBJECT (bin));
  std_log(LOG_FILENAME_LINE, "Test Successful");
    create_xml(0);
}
예제 #12
0
void test_play_twice()
{
  GstElement *bin, *src1, *src2, *adder, *sink;
  GstBus *bus;
  gboolean res;
  //xmlfile = "test_play_twice";
    std_log(LOG_FILENAME_LINE, "Test Started test_play_twice");
  GST_INFO ("preparing test");

  /* build pipeline */
  bin = gst_pipeline_new ("pipeline");
  bus = gst_element_get_bus (bin);
  gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);

  src1 = gst_element_factory_make ("audiotestsrc", "src1");
  g_object_set (src1, "wave", 4, NULL); /* silence */
  src2 = gst_element_factory_make ("audiotestsrc", "src2");
  g_object_set (src2, "wave", 4, NULL); /* silence */
  adder = gst_element_factory_make ("adder", "adder");
  sink = gst_element_factory_make ("fakesink", "sink");
  gst_bin_add_many (GST_BIN (bin), src1, src2, adder, sink, NULL);

  res = gst_element_link (src1, adder);
  fail_unless (res == TRUE, NULL);
  res = gst_element_link (src2, adder);
  fail_unless (res == TRUE, NULL);
  res = gst_element_link (adder, sink);
  fail_unless (res == TRUE, NULL);

  play_seek_event = gst_event_new_seek (1.0, GST_FORMAT_TIME,
      GST_SEEK_FLAG_SEGMENT | GST_SEEK_FLAG_FLUSH,
      GST_SEEK_TYPE_SET, (GstClockTime) 0,
      GST_SEEK_TYPE_SET, (GstClockTime) 2 * GST_SECOND);

  play_count = 0;

  main_loop = g_main_loop_new (NULL, FALSE);
  g_signal_connect (bus, "message::segment-done",
      (GCallback) test_play_twice_message_received, bin);
  g_signal_connect (bus, "message::error", (GCallback) message_received, bin);
  g_signal_connect (bus, "message::warning", (GCallback) message_received, bin);
  g_signal_connect (bus, "message::eos", (GCallback) message_received, bin);

  GST_INFO ("starting test");

  /* prepare playing */
  res = gst_element_set_state (bin, GST_STATE_PAUSED);
  fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);

  /* wait for completion */
  res =
      gst_element_get_state (GST_ELEMENT (bin), NULL, NULL,
      GST_CLOCK_TIME_NONE);
  fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);

  res = gst_element_send_event (bin, gst_event_ref (play_seek_event));
  fail_unless (res == TRUE, NULL);

  /* run pipeline */
  res = gst_element_set_state (bin, GST_STATE_PLAYING);
  fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);

  g_main_loop_run (main_loop);

  res = gst_element_set_state (bin, GST_STATE_NULL);
  fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);

  fail_unless (play_count == 2, NULL);

  /* cleanup */
  g_main_loop_unref (main_loop);
  gst_object_unref (G_OBJECT (bus));
  gst_object_unref (G_OBJECT (bin));
  std_log(LOG_FILENAME_LINE, "Test Successful");
    create_xml(0);
}
/*
 * Create a demux element, run a test using the input data and check
 * the output data
 */
void
gst_adaptive_demux_test_run (const gchar * element_name,
    const gchar * manifest_uri,
    const GstAdaptiveDemuxTestCallbacks * callbacks, gpointer user_data)
{
  GstBus *bus;
  GstElement *demux;
  GstElement *manifest_source;
  gboolean ret;
  GstStateChangeReturn stateChange;
  GstAdaptiveDemuxTestEnginePrivate *priv;

  priv = g_slice_new0 (GstAdaptiveDemuxTestEnginePrivate);
  priv->engine.output_streams =
      g_ptr_array_new_with_free_func
      (adaptive_demux_engine_stream_state_finalize);
  g_mutex_init (&priv->engine.lock);
  priv->callbacks = callbacks;
  priv->user_data = user_data;
  priv->engine.loop = g_main_loop_new (NULL, TRUE);
  fail_unless (priv->engine.loop != NULL);
  GST_TEST_LOCK (priv);
  priv->engine.pipeline = gst_pipeline_new ("pipeline");
  fail_unless (priv->engine.pipeline != NULL);
  GST_DEBUG ("created pipeline %" GST_PTR_FORMAT, priv->engine.pipeline);

  /* register a callback to listen for error messages */
  bus = gst_pipeline_get_bus (GST_PIPELINE (priv->engine.pipeline));
  gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);
  g_signal_connect (bus, "message::error",
      G_CALLBACK (on_ErrorMessageOnBus), priv);

  manifest_source =
      gst_element_make_from_uri (GST_URI_SRC, manifest_uri, NULL, NULL);
  fail_unless (manifest_source != NULL);
  priv->engine.manifest_source = manifest_source;

  demux = gst_check_setup_element (element_name);
  fail_unless (demux != NULL);
  priv->engine.demux = demux;
  GST_DEBUG ("created demux %" GST_PTR_FORMAT, demux);

  g_signal_connect (demux, "element-added", G_CALLBACK (on_demuxElementAdded),
      priv);
  g_signal_connect (demux, "pad-added", G_CALLBACK (on_demuxNewPad), priv);
  g_signal_connect (demux, "pad-removed",
      G_CALLBACK (on_demuxPadRemoved), priv);

  gst_bin_add_many (GST_BIN (priv->engine.pipeline), manifest_source, demux,
      NULL);
  ASSERT_OBJECT_REFCOUNT (manifest_source, element_name, 1);
  ASSERT_OBJECT_REFCOUNT (demux, element_name, 1);

  ret = gst_element_link (manifest_source, demux);
  fail_unless_equals_int (ret, TRUE);

  priv->engine.clock = gst_system_clock_obtain ();
  if (GST_IS_TEST_CLOCK (priv->engine.clock)) {
    /*
     * live tests will want to manipulate the clock, so they will register a
     * gst_test_clock as the system clock.
     * The on demand tests do not care about the clock, so they will let the
     * system clock to the default one.
     * If a gst_test_clock was installed as system clock, we register a
     * periodic callback to update its value.
     */
    priv->clock_update_id =
        g_timeout_add (100, gst_adaptive_demux_update_test_clock, priv);
  }

  /* call a test callback before we start the pipeline */
  if (callbacks->pre_test)
    (*callbacks->pre_test) (&priv->engine, priv->user_data);

  GST_TEST_UNLOCK (priv);

  GST_DEBUG ("Starting pipeline");
  stateChange = gst_element_set_state (priv->engine.pipeline, GST_STATE_PAUSED);
  fail_unless (stateChange != GST_STATE_CHANGE_FAILURE);
  /* wait for completion of the move to PAUSED */
  stateChange = gst_element_get_state (priv->engine.pipeline, NULL, NULL,
      GST_CLOCK_TIME_NONE);
  fail_unless (stateChange != GST_STATE_CHANGE_FAILURE);

  g_idle_add ((GSourceFunc) start_pipeline_playing, priv);

  /* block until a callback calls g_main_loop_quit (engine.loop) */
  GST_DEBUG ("main thread waiting for streams to finish");
  g_main_loop_run (priv->engine.loop);
  GST_DEBUG ("main thread finished. Stopping pipeline");

  /* no need to use gst_element_get_state as the move the GST_STATE_NULL
     is always synchronous */
  stateChange = gst_element_set_state (priv->engine.pipeline, GST_STATE_NULL);
  fail_unless (stateChange != GST_STATE_CHANGE_FAILURE);

  GST_TEST_LOCK (priv);

  /* call a test callback after the stop of the pipeline */
  if (callbacks->post_test)
    (*callbacks->post_test) (&priv->engine, priv->user_data);

  g_signal_handlers_disconnect_by_func (bus,
      G_CALLBACK (on_ErrorMessageOnBus), priv);
  gst_bus_remove_signal_watch (bus);
  g_signal_handlers_disconnect_by_func (demux, G_CALLBACK (on_demuxNewPad),
      priv);
  g_signal_handlers_disconnect_by_func (demux, G_CALLBACK (on_demuxPadRemoved),
      priv);

  GST_DEBUG ("main thread pipeline stopped");
  if (priv->clock_update_id != 0)
    g_source_remove (priv->clock_update_id);
  gst_object_unref (priv->engine.clock);
  gst_object_unref (priv->engine.pipeline);
  priv->engine.pipeline = NULL;
  g_main_loop_unref (priv->engine.loop);
  g_ptr_array_unref (priv->engine.output_streams);
  gst_object_unref (bus);

  GST_TEST_UNLOCK (priv);
  g_mutex_clear (&priv->engine.lock);
  g_slice_free (GstAdaptiveDemuxTestEnginePrivate, priv);
}