From 944558971d85e7b3463813d59b9fa052bba025fd Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Fri, 26 Feb 2010 13:56:21 +0200 Subject: [PATCH] tests: add a test for trickplay in audio synthesis graphs Right now this mostly demonstatest what not works. That is seeking with start-type = NONE to only update the rate and playing backwards. Also it shows that non-flushing seeks tend to lockup adder. Separate unit tests for the issues follow. --- tests/icles/.gitignore | 3 +- tests/icles/Makefile.am | 15 ++-- tests/icles/audio-trickplay.c | 203 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 215 insertions(+), 6 deletions(-) create mode 100644 tests/icles/audio-trickplay.c diff --git a/tests/icles/.gitignore b/tests/icles/.gitignore index 82bd9b2..ae231a1 100644 --- a/tests/icles/.gitignore +++ b/tests/icles/.gitignore @@ -1,3 +1,5 @@ +audio-trickplay +playbin-text stress-playbin stress-xoverlay test-textoverlay @@ -5,4 +7,3 @@ test-scale test-box test-colorkey test-xoverlay -playbin-text diff --git a/tests/icles/Makefile.am b/tests/icles/Makefile.am index a88a832..6923e6d 100644 --- a/tests/icles/Makefile.am +++ b/tests/icles/Makefile.am @@ -35,6 +35,14 @@ else PANGO_TESTS = endif +audio_trickplay_SOURCES = audio-trickplay.c +audio_trickplay_CFLAGS = $(GST_CFLAGS) +audio_trickplay_LDADD = $(GST_LIBS) -lgstcontroller-$(GST_MAJORMINOR) $(LIBM) + +playbin_text_SOURCES = playbin-text.c +playbin_text_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) +playbin_text_LDADD = $(GST_LIBS) $(LIBM) + stress_playbin_SOURCES = stress-playbin.c stress_playbin_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) stress_playbin_LDADD = $(GST_LIBS) $(LIBM) @@ -47,8 +55,5 @@ test_box_SOURCES = test-box.c test_box_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) test_box_LDADD = $(GST_LIBS) $(LIBM) -playbin_text_SOURCES = playbin-text.c -playbin_text_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) -playbin_text_LDADD = $(GST_LIBS) $(LIBM) - -noinst_PROGRAMS = $(X_TESTS) $(PANGO_TESTS) stress-playbin test-scale test-box playbin-text +noinst_PROGRAMS = $(X_TESTS) $(PANGO_TESTS) \ + audio-trickplay playbin-text stress-playbin test-scale test-box diff --git a/tests/icles/audio-trickplay.c b/tests/icles/audio-trickplay.c new file mode 100644 index 0000000..64440cd --- /dev/null +++ b/tests/icles/audio-trickplay.c @@ -0,0 +1,203 @@ +/* + * audio-trickplay.c + * + * Builds a pipeline with two audiotestsources mixed with adder. Assigns + * controller patterns to the audio generators and test various trick modes. + */ + +#include +#include +#include + +static void +check_position (GstElement * sink, GstQuery * pos, const gchar * info) +{ + if (gst_element_query (sink, pos)) { + gint64 play_pos; + gst_query_parse_position (pos, NULL, &play_pos); + printf ("pos: %" GST_TIME_FORMAT " %s\n", GST_TIME_ARGS (play_pos), info); + } else { + GST_WARNING ("position query failed"); + } +} + +gint +main (gint argc, gchar ** argv) +{ + gint res = 1; + GstElement *src, *mix, *sink; + GstElement *bin; + GstController *ctrl; + GstInterpolationControlSource *csource1, *csource2; + GstClock *clock; + GstClockID clock_id; + GstClockReturn wait_ret; + GValue vol = { 0, }; + GstEvent *pos_seek, *rate_seek; + GstQuery *pos; + /* options */ + gboolean use_adder; + + gst_init (&argc, &argv); + gst_controller_init (&argc, &argv); + + if (argc) { + gint arg; + for (arg = 0; arg < argc; arg++) { + if (!strcmp (argv[arg], "-a")) + use_adder = TRUE; + } + } + + /* build pipeline */ + bin = gst_pipeline_new ("pipeline"); + clock = gst_pipeline_get_clock (GST_PIPELINE (bin)); + src = gst_element_factory_make ("audiotestsrc", NULL); + if (!src) { + GST_WARNING ("need audiotestsrc from gst-plugins-base"); + goto Error; + } + if (use_adder) { + mix = gst_element_factory_make ("adder", NULL); + if (!src) { + GST_WARNING ("need adder from gst-plugins-base"); + goto Error; + } + } + sink = gst_element_factory_make ("autoaudiosink", NULL); + if (!sink) { + GST_WARNING ("need autoaudiosink from gst-plugins-base"); + goto Error; + } + + if (use_adder) { + gst_bin_add_many (GST_BIN (bin), src, mix, sink, NULL); + if (!gst_element_link_many (src, mix, sink, NULL)) { + GST_WARNING ("can't link elements"); + goto Error; + } + } else { + gst_bin_add_many (GST_BIN (bin), src, sink, NULL); + if (!gst_element_link_many (src, sink, NULL)) { + GST_WARNING ("can't link elements"); + goto Error; + } + } + + /* add a controller to the source */ + if (!(ctrl = gst_controller_new (G_OBJECT (src), "freq", "volume", NULL))) { + GST_WARNING ("can't control source element"); + goto Error; + } + + csource1 = gst_interpolation_control_source_new (); + csource2 = gst_interpolation_control_source_new (); + + gst_controller_set_control_source (ctrl, "volume", + GST_CONTROL_SOURCE (csource1)); + gst_controller_set_control_source (ctrl, "freq", + GST_CONTROL_SOURCE (csource2)); + + /* Set interpolation mode */ + + gst_interpolation_control_source_set_interpolation_mode (csource1, + GST_INTERPOLATE_LINEAR); + gst_interpolation_control_source_set_interpolation_mode (csource2, + GST_INTERPOLATE_LINEAR); + + /* set control values */ + g_value_init (&vol, G_TYPE_DOUBLE); + g_value_set_double (&vol, 0.0); + gst_interpolation_control_source_set (csource1, 0 * GST_SECOND, &vol); + g_value_set_double (&vol, 1.0); + gst_interpolation_control_source_set (csource1, 5 * GST_SECOND, &vol); + + g_object_unref (csource1); + + g_value_set_double (&vol, 220.0); + gst_interpolation_control_source_set (csource2, 0 * GST_SECOND, &vol); + g_value_set_double (&vol, 3520.0); + gst_interpolation_control_source_set (csource2, 2 * GST_SECOND, &vol); + g_value_set_double (&vol, 440.0); + gst_interpolation_control_source_set (csource2, 6 * GST_SECOND, &vol); + + g_object_unref (csource2); + + /* prepare events */ + pos_seek = gst_event_new_seek (1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_NONE, + GST_SEEK_TYPE_SET, 3 * GST_SECOND, + GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE); + rate_seek = gst_event_new_seek (0.5, GST_FORMAT_TIME, GST_SEEK_FLAG_NONE, + GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE, + GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE); + + /* prepare queries */ + pos = gst_query_new_position (GST_FORMAT_TIME); + + + /* run the show */ + if (gst_element_set_state (bin, GST_STATE_PAUSED)) { + + /* run for 5 seconds */ + clock_id = + gst_clock_new_single_shot_id (clock, + gst_clock_get_time (clock) + (5 * GST_SECOND)); + + if (gst_element_set_state (bin, GST_STATE_PLAYING)) { + check_position (sink, pos, "start"); + if ((wait_ret = gst_clock_id_wait (clock_id, NULL)) != GST_CLOCK_OK) { + GST_WARNING ("clock_id_wait returned: %d", wait_ret); + } + } + gst_clock_id_unref (clock_id); + + check_position (sink, pos, "before seek to new pos"); + + /* seek to 3:00 sec (back 2 sec) */ + if (!gst_element_send_event (sink, pos_seek)) { + GST_WARNING ("element failed to seek to new position"); + } + + check_position (sink, pos, "after seek to new pos"); + + /* run for 2 seconds */ + clock_id = + gst_clock_new_single_shot_id (clock, + gst_clock_get_time (clock) + (2 * GST_SECOND)); + if ((wait_ret = gst_clock_id_wait (clock_id, NULL)) != GST_CLOCK_OK) { + GST_WARNING ("clock_id_wait returned: %d", wait_ret); + } + gst_clock_id_unref (clock_id); + + check_position (sink, pos, "before rate change"); + + /* change playback rate */ + if (!gst_element_send_event (sink, rate_seek)) { + GST_WARNING ("element failed to change playback rate"); + } + + check_position (sink, pos, "after rate change"); + + /* run for 4 seconds */ + clock_id = + gst_clock_new_single_shot_id (clock, + gst_clock_get_time (clock) + (4 * GST_SECOND)); + if ((wait_ret = gst_clock_id_wait (clock_id, NULL)) != GST_CLOCK_OK) { + GST_WARNING ("clock_id_wait returned: %d", wait_ret); + } + gst_clock_id_unref (clock_id); + + check_position (sink, pos, "done"); + + gst_element_set_state (bin, GST_STATE_NULL); + } + + /* cleanup */ + gst_query_unref (pos); + g_object_unref (G_OBJECT (ctrl)); + gst_object_unref (G_OBJECT (clock)); + gst_object_unref (G_OBJECT (bin)); + res = 0; +Error: + return (res); +} -- 2.7.4