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