diff options
Diffstat (limited to 'subprojects/gst-libav/tests/check')
-rw-r--r-- | subprojects/gst-libav/tests/check/elements/avaudenc.c | 126 | ||||
-rw-r--r-- | subprojects/gst-libav/tests/check/elements/avdec_adpcm.c | 168 | ||||
-rw-r--r-- | subprojects/gst-libav/tests/check/elements/avdemux_ape.c | 206 | ||||
-rw-r--r-- | subprojects/gst-libav/tests/check/elements/avvidenc.c | 116 | ||||
-rw-r--r-- | subprojects/gst-libav/tests/check/generic/libavcodec-locking.c | 161 | ||||
-rw-r--r-- | subprojects/gst-libav/tests/check/generic/plugin-test.c | 98 | ||||
-rw-r--r-- | subprojects/gst-libav/tests/check/gst-libav.supp | 0 | ||||
-rw-r--r-- | subprojects/gst-libav/tests/check/meson.build | 60 |
8 files changed, 935 insertions, 0 deletions
diff --git a/subprojects/gst-libav/tests/check/elements/avaudenc.c b/subprojects/gst-libav/tests/check/elements/avaudenc.c new file mode 100644 index 0000000000..e4403d7243 --- /dev/null +++ b/subprojects/gst-libav/tests/check/elements/avaudenc.c @@ -0,0 +1,126 @@ +/* GStreamer + * + * Copyright (C) 2020 Seungha Yang <seungha@centricular.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gst/check/gstcheck.h> +#include <gst/check/gstharness.h> +#include <gst/audio/audio.h> + +GST_START_TEST (test_audioenc_drain) +{ + GstHarness *h; + GstAudioInfo info; + GstBuffer *in_buf; + gint i = 0; + gint num_output = 0; + GstFlowReturn ret; + GstSegment segment; + GstCaps *caps; + gint samples_per_buffer = 1024; + gint rate = 44100; + gint size; + GstClockTime duration; + + h = gst_harness_new ("avenc_aac"); + fail_unless (h != NULL); + + gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_F32, rate, 1, NULL); + + caps = gst_audio_info_to_caps (&info); + gst_harness_set_src_caps (h, gst_caps_copy (caps)); + + duration = gst_util_uint64_scale_int (samples_per_buffer, GST_SECOND, rate); + size = samples_per_buffer * GST_AUDIO_INFO_BPF (&info); + + for (i = 0; i < 2; i++) { + in_buf = gst_buffer_new_and_alloc (size); + + gst_buffer_memset (in_buf, 0, 0, size); + + /* small rounding error would be expected, but should be fine */ + GST_BUFFER_PTS (in_buf) = i * duration; + GST_BUFFER_DURATION (in_buf) = duration; + + ret = gst_harness_push (h, in_buf); + + fail_unless (ret == GST_FLOW_OK, "GstFlowReturn was %s", + gst_flow_get_name (ret)); + } + + gst_segment_init (&segment, GST_FORMAT_TIME); + fail_unless (gst_segment_set_running_time (&segment, GST_FORMAT_TIME, + 2 * duration)); + + /* Push new eos event to drain encoder */ + fail_unless (gst_harness_push_event (h, gst_event_new_eos ())); + + /* And start new stream */ + fail_unless (gst_harness_push_event (h, + gst_event_new_stream_start ("new-stream-id"))); + gst_harness_set_src_caps (h, caps); + fail_unless (gst_harness_push_event (h, gst_event_new_segment (&segment))); + + in_buf = gst_buffer_new_and_alloc (size); + + GST_BUFFER_PTS (in_buf) = 2 * duration; + GST_BUFFER_DURATION (in_buf) = duration; + + ret = gst_harness_push (h, in_buf); + fail_unless (ret == GST_FLOW_OK, "GstFlowReturn was %s", + gst_flow_get_name (ret)); + + /* Finish encoding and drain again */ + fail_unless (gst_harness_push_event (h, gst_event_new_eos ())); + do { + GstBuffer *out_buf = NULL; + + out_buf = gst_harness_try_pull (h); + if (out_buf) { + num_output++; + gst_buffer_unref (out_buf); + continue; + } + + break; + } while (1); + + fail_unless (num_output >= 3); + + gst_harness_teardown (h); +} + +GST_END_TEST; + +static Suite * +avaudenc_suite (void) +{ + Suite *s = suite_create ("avaudenc"); + TCase *tc_chain = tcase_create ("general"); + + suite_add_tcase (s, tc_chain); + tcase_add_test (tc_chain, test_audioenc_drain); + + return s; +} + +GST_CHECK_MAIN (avaudenc) diff --git a/subprojects/gst-libav/tests/check/elements/avdec_adpcm.c b/subprojects/gst-libav/tests/check/elements/avdec_adpcm.c new file mode 100644 index 0000000000..2bc745d5ae --- /dev/null +++ b/subprojects/gst-libav/tests/check/elements/avdec_adpcm.c @@ -0,0 +1,168 @@ +/* GStreamer unit tests for avdec_adpcm + * + * Copyright (C) 2009 Tim-Philipp Müller <tim centricular net> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <gst/check/gstcheck.h> + +#include <gst/gst.h> + +static void +pad_added_cb (GstElement * decodebin, GstPad * pad, GstBin * pipeline) +{ + GstElement *sink; + + GST_INFO_OBJECT (pad, "got pad"); + + sink = gst_bin_get_by_name (pipeline, "fakesink"); + fail_unless (gst_element_link (decodebin, sink)); + gst_object_unref (sink); + + gst_element_set_state (sink, GST_STATE_PAUSED); +} + +static GstBusSyncReply +error_cb (GstBus * bus, GstMessage * msg, gpointer user_data) +{ + if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) { + const gchar *file = (const gchar *) user_data; + GError *err = NULL; + gchar *dbg = NULL; + + gst_message_parse_error (msg, &err, &dbg); + g_error ("ERROR for %s: %s\n%s\n", file, err->message, dbg); + } + + return GST_BUS_PASS; +} + +static gboolean +decode_file (const gchar * file, gboolean push_mode) +{ + GstStateChangeReturn state_ret; + GstElement *sink, *src, *dec, *queue, *pipeline; + GstMessage *msg; + GstBus *bus; + gchar *path; + + pipeline = gst_pipeline_new ("pipeline"); + fail_unless (pipeline != NULL, "Failed to create pipeline!"); + + src = gst_element_factory_make ("filesrc", "filesrc"); + fail_unless (src != NULL, "Failed to create filesrc!"); + + if (push_mode) { + queue = gst_element_factory_make ("queue", "queue"); + } else { + queue = gst_element_factory_make ("identity", "identity"); + } + + dec = gst_element_factory_make ("decodebin", "decodebin"); + fail_unless (dec != NULL, "Failed to create decodebin!"); + + sink = gst_element_factory_make ("fakesink", "fakesink"); + fail_unless (sink != NULL, "Failed to create fakesink!"); + + bus = gst_element_get_bus (pipeline); + + /* kids, don't use a sync handler for this at home, really; we do because + * we just want to abort and nothing else */ + gst_bus_set_sync_handler (bus, error_cb, (gpointer) file, NULL); + + gst_bin_add_many (GST_BIN (pipeline), src, queue, dec, sink, NULL); + gst_element_link_many (src, queue, dec, NULL); + + path = g_build_filename (GST_TEST_FILES_PATH, file, NULL); + GST_LOG ("reading file '%s'", path); + g_object_set (src, "location", path, NULL); + + /* can't link uridecodebin and sink yet, do that later */ + g_signal_connect (dec, "pad-added", G_CALLBACK (pad_added_cb), pipeline); + + state_ret = gst_element_set_state (pipeline, GST_STATE_PAUSED); + fail_unless (state_ret != GST_STATE_CHANGE_FAILURE); + + if (state_ret == GST_STATE_CHANGE_ASYNC) { + GST_LOG ("waiting for pipeline to reach PAUSED state"); + state_ret = gst_element_get_state (pipeline, NULL, NULL, -1); + fail_unless_equals_int (state_ret, GST_STATE_CHANGE_SUCCESS); + } + + state_ret = gst_element_set_state (pipeline, GST_STATE_PLAYING); + fail_unless (state_ret != GST_STATE_CHANGE_FAILURE); + + GST_LOG ("PAUSED, let's decode"); + msg = gst_bus_timed_pop_filtered (bus, 10 * GST_SECOND, GST_MESSAGE_EOS); + GST_LOG ("Done, got EOS message"); + fail_unless (msg != NULL); + gst_message_unref (msg); + gst_object_unref (bus); + + fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_NULL), + GST_STATE_CHANGE_SUCCESS); + gst_object_unref (pipeline); + + g_free (path); + + return TRUE; +} + +static void +run_check_for_file (const gchar * filename) +{ + gboolean ret; + + /* first, pull-based */ + ret = decode_file (filename, FALSE); + fail_unless (ret == TRUE, "Failed to decode '%s' (pull mode)", filename); + + /* second, push-based */ + ret = decode_file (filename, TRUE); + fail_unless (ret == TRUE, "Failed to decode '%s' (push mode)", filename); +} + +GST_START_TEST (test_low_sample_rate_adpcm) +{ +#define MIN_VERSION GST_VERSION_MAJOR, GST_VERSION_MINOR, 0 + if (!gst_registry_check_feature_version (gst_registry_get (), "wavparse", + MIN_VERSION) + || !gst_registry_check_feature_version (gst_registry_get (), "decodebin", + MIN_VERSION)) { + g_printerr ("skipping test_low_sample_rate_adpcm: required element " + "wavparse or element decodebin not found\n"); + return; + } + + run_check_for_file ("591809.wav"); +} + +GST_END_TEST; + +static Suite * +avdec_adpcm_suite (void) +{ + Suite *s = suite_create ("avdec_adpcm"); + TCase *tc_chain = tcase_create ("general"); + + suite_add_tcase (s, tc_chain); + tcase_skip_broken_test (tc_chain, test_low_sample_rate_adpcm); + + return s; +} + +GST_CHECK_MAIN (avdec_adpcm) diff --git a/subprojects/gst-libav/tests/check/elements/avdemux_ape.c b/subprojects/gst-libav/tests/check/elements/avdemux_ape.c new file mode 100644 index 0000000000..99dbd7617b --- /dev/null +++ b/subprojects/gst-libav/tests/check/elements/avdemux_ape.c @@ -0,0 +1,206 @@ +/* GStreamer unit tests for avdemux_ape + * + * Copyright (C) 2009 Tim-Philipp Müller <tim centricular net> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <gst/check/gstcheck.h> + +#include <gst/gst.h> + +typedef void (CheckTagsFunc) (const GstTagList * tags, const gchar * file); + +static void +pad_added_cb (GstElement * decodebin, GstPad * pad, GstBin * pipeline) +{ + GstElement *sink; + + sink = gst_bin_get_by_name (pipeline, "fakesink"); + fail_unless (gst_element_link (decodebin, sink)); + gst_object_unref (sink); + + gst_element_set_state (sink, GST_STATE_PAUSED); +} + +static GstBusSyncReply +error_cb (GstBus * bus, GstMessage * msg, gpointer user_data) +{ + if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) { + const gchar *file = (const gchar *) user_data; + GError *err = NULL; + gchar *dbg = NULL; + + gst_message_parse_error (msg, &err, &dbg); + g_error ("ERROR for %s: %s\n%s\n", file, err->message, dbg); + } + + return GST_BUS_PASS; +} + +static GstPadProbeReturn +event_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data) +{ + GstTagList **p_tags = user_data; + GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info); + + if (GST_EVENT_TYPE (event) == GST_EVENT_TAG) { + GST_INFO ("tag event: %" GST_PTR_FORMAT, event); + if (*p_tags == NULL) { + GstTagList *event_tags; + + GST_INFO ("first tag, saving"); + gst_event_parse_tag (event, &event_tags); + *p_tags = gst_tag_list_copy (event_tags); + } + } + return GST_PAD_PROBE_OK; /* keep the data */ +} + +/* FIXME: push_mode not used currently */ +static GstTagList * +read_tags_from_file (const gchar * file, gboolean push_mode) +{ + GstStateChangeReturn state_ret; + GstTagList *tags = NULL; + GstElement *sink, *src, *dec, *pipeline; + GstBus *bus; + GstPad *pad; + gchar *path; + + pipeline = gst_pipeline_new ("pipeline"); + fail_unless (pipeline != NULL, "Failed to create pipeline!"); + + src = gst_element_factory_make ("filesrc", "filesrc"); + fail_unless (src != NULL, "Failed to create filesrc!"); + + dec = gst_element_factory_make ("decodebin", "decodebin"); + fail_unless (dec != NULL, "Failed to create decodebin!"); + + sink = gst_element_factory_make ("fakesink", "fakesink"); + fail_unless (sink != NULL, "Failed to create fakesink!"); + + bus = gst_element_get_bus (pipeline); + + /* kids, don't use a sync handler for this at home, really; we do because + * we just want to abort and nothing else */ + gst_bus_set_sync_handler (bus, error_cb, (gpointer) file, NULL); + + gst_bin_add_many (GST_BIN (pipeline), src, dec, sink, NULL); + gst_element_link_many (src, dec, NULL); + + path = g_build_filename (GST_TEST_FILES_PATH, file, NULL); + GST_LOG ("reading file '%s'", path); + g_object_set (src, "location", path, NULL); + + /* can't link uridecodebin and sink yet, do that later */ + g_signal_connect (dec, "pad-added", G_CALLBACK (pad_added_cb), pipeline); + + /* we want to make sure there's a tag event coming out of avdemux_ape + * (ie. the one apedemux generated) */ + pad = gst_element_get_static_pad (sink, "sink"); + gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, event_probe, + &tags, NULL); + gst_object_unref (pad); + + state_ret = gst_element_set_state (pipeline, GST_STATE_PAUSED); + fail_unless (state_ret != GST_STATE_CHANGE_FAILURE); + + if (state_ret == GST_STATE_CHANGE_ASYNC) { + GST_LOG ("waiting for pipeline to reach PAUSED state"); + state_ret = gst_element_get_state (pipeline, NULL, NULL, -1); + fail_unless_equals_int (state_ret, GST_STATE_CHANGE_SUCCESS); + } + + GST_LOG ("PAUSED, let's retrieve our tags"); + + fail_unless (tags != NULL, "Expected tag event! (%s)", file); + + gst_object_unref (bus); + + fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_NULL), + GST_STATE_CHANGE_SUCCESS); + gst_object_unref (pipeline); + + g_free (path); + + GST_INFO ("%s: tags = %" GST_PTR_FORMAT, file, tags); + return tags; +} + +static void +run_check_for_file (const gchar * filename, CheckTagsFunc * check_func) +{ + GstTagList *tags; + + /* first, pull-based */ + tags = read_tags_from_file (filename, FALSE); + fail_unless (tags != NULL, "Failed to extract tags from '%s'", filename); + check_func (tags, filename); + gst_tag_list_unref (tags); +} + +#define tag_list_has_tag(taglist,tag) \ + (gst_tag_list_get_value_index((taglist),(tag),0) != NULL) + +/* just make sure avdemux_ape forwarded the tags extracted by apedemux + * (should be the first tag list / tag event too) */ +static void +check_for_apedemux_tags (const GstTagList * tags, const gchar * file) +{ + gchar *artist = NULL; + + fail_unless (gst_tag_list_get_string (tags, GST_TAG_ARTIST, &artist)); + fail_unless (artist != NULL); + fail_unless_equals_string (artist, "Marvin Gaye"); + g_free (artist); + + fail_unless (tag_list_has_tag (tags, GST_TAG_CONTAINER_FORMAT)); + + GST_LOG ("all good"); +} + +GST_START_TEST (test_tag_caching) +{ +#define MIN_VERSION GST_VERSION_MAJOR, GST_VERSION_MINOR, 0 + + if (!gst_registry_check_feature_version (gst_registry_get (), "apedemux", + MIN_VERSION) + || !gst_registry_check_feature_version (gst_registry_get (), "decodebin", + MIN_VERSION)) { + g_printerr ("Skipping test_tag_caching: required element apedemux or " + "decodebin element not found\n"); + return; + } + + run_check_for_file ("586957.ape", check_for_apedemux_tags); +} + +GST_END_TEST; + +static Suite * +avdemux_ape_suite (void) +{ + Suite *s = suite_create ("avdemux_ape"); + TCase *tc_chain = tcase_create ("general"); + + suite_add_tcase (s, tc_chain); + tcase_add_test (tc_chain, test_tag_caching); + + return s; +} + +GST_CHECK_MAIN (avdemux_ape) diff --git a/subprojects/gst-libav/tests/check/elements/avvidenc.c b/subprojects/gst-libav/tests/check/elements/avvidenc.c new file mode 100644 index 0000000000..04ca20d1be --- /dev/null +++ b/subprojects/gst-libav/tests/check/elements/avvidenc.c @@ -0,0 +1,116 @@ +/* GStreamer + * + * Copyright (C) 2020 Seungha Yang <seungha@centricular.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gst/check/gstcheck.h> +#include <gst/check/gstharness.h> +#include <gst/video/video.h> + +GST_START_TEST (test_videoenc_drain) +{ + GstHarness *h; + GstVideoInfo info; + GstBuffer *in_buf; + gint i = 0; + gint num_output = 0; + GstFlowReturn ret; + GstSegment segment; + GstCaps *caps; + + h = gst_harness_new ("avenc_mjpeg"); + fail_unless (h != NULL); + + caps = gst_caps_from_string ("video/x-raw,format=I420,width=64,height=64"); + + gst_harness_set_src_caps (h, gst_caps_copy (caps)); + gst_video_info_set_format (&info, GST_VIDEO_FORMAT_I420, 64, 64); + + for (i = 0; i < 2; i++) { + in_buf = gst_buffer_new_and_alloc (GST_VIDEO_INFO_SIZE (&info)); + + GST_BUFFER_PTS (in_buf) = i * GST_SECOND; + GST_BUFFER_DURATION (in_buf) = GST_SECOND; + + ret = gst_harness_push (h, in_buf); + + fail_unless (ret == GST_FLOW_OK, "GstFlowReturn was %s", + gst_flow_get_name (ret)); + } + + gst_segment_init (&segment, GST_FORMAT_TIME); + fail_unless (gst_segment_set_running_time (&segment, GST_FORMAT_TIME, + 2 * GST_SECOND)); + + /* Push new eos event to drain encoder */ + fail_unless (gst_harness_push_event (h, gst_event_new_eos ())); + + /* And start new stream */ + fail_unless (gst_harness_push_event (h, + gst_event_new_stream_start ("new-stream-id"))); + gst_harness_set_src_caps (h, caps); + fail_unless (gst_harness_push_event (h, gst_event_new_segment (&segment))); + + in_buf = gst_buffer_new_and_alloc (GST_VIDEO_INFO_SIZE (&info)); + + GST_BUFFER_PTS (in_buf) = 2 * GST_SECOND; + GST_BUFFER_DURATION (in_buf) = GST_SECOND; + + ret = gst_harness_push (h, in_buf); + fail_unless (ret == GST_FLOW_OK, "GstFlowReturn was %s", + gst_flow_get_name (ret)); + + /* Finish encoding and drain again */ + fail_unless (gst_harness_push_event (h, gst_event_new_eos ())); + do { + GstBuffer *out_buf = NULL; + + out_buf = gst_harness_try_pull (h); + if (out_buf) { + num_output++; + gst_buffer_unref (out_buf); + continue; + } + + break; + } while (1); + + fail_unless_equals_int (num_output, 3); + + gst_harness_teardown (h); +} + +GST_END_TEST; + +static Suite * +avvidenc_suite (void) +{ + Suite *s = suite_create ("avvidenc"); + TCase *tc_chain = tcase_create ("general"); + + suite_add_tcase (s, tc_chain); + tcase_add_test (tc_chain, test_videoenc_drain); + + return s; +} + +GST_CHECK_MAIN (avvidenc) diff --git a/subprojects/gst-libav/tests/check/generic/libavcodec-locking.c b/subprojects/gst-libav/tests/check/generic/libavcodec-locking.c new file mode 100644 index 0000000000..a6dfb8e29d --- /dev/null +++ b/subprojects/gst-libav/tests/check/generic/libavcodec-locking.c @@ -0,0 +1,161 @@ +/* GStreamer + * Copyright (C) 2005 Luca Ognibene <luogni@tin.it> + * Based (copied) on simple_launch_lines.c + * + * libavcodec-locking.c: Unit test for libavcodec's locks + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + + +#include <gst/check/gstcheck.h> +#include <stdlib.h> + +#define NUM_SINKS 10 + +static GstElement * +setup_pipeline (const gchar * pipe_descr) +{ + GstElement *pipeline; + + pipeline = gst_parse_launch (pipe_descr, NULL); + g_return_val_if_fail (GST_IS_PIPELINE (pipeline), NULL); + return pipeline; +} + +/* + * run_pipeline: + * @pipe: the pipeline to run + * @desc: the description for use in messages + * @events: is a mask of expected events + * @tevent: is the expected terminal event. + * + * the poll call will time out after half a second. + */ +static void +run_pipeline (GstElement * pipe, const gchar * descr, + GstMessageType events, GstMessageType tevent) +{ + GstBus *bus; + GstMessage *message; + GstMessageType revent; + GstStateChangeReturn ret; + + g_assert (pipe); + bus = gst_element_get_bus (pipe); + g_assert (bus); + + ret = gst_element_set_state (pipe, GST_STATE_PLAYING); + ret = gst_element_get_state (pipe, NULL, NULL, GST_CLOCK_TIME_NONE); + if (ret != GST_STATE_CHANGE_SUCCESS) { + g_critical ("Couldn't set pipeline to PLAYING"); + goto done; + } + + while (1) { + message = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 2); + + /* always have to pop the message before getting back into poll */ + if (message) { + revent = GST_MESSAGE_TYPE (message); + gst_message_unref (message); + } else { + revent = GST_MESSAGE_UNKNOWN; + } + + if (revent == tevent) { + break; + } else if (revent == GST_MESSAGE_UNKNOWN) { + g_critical ("Unexpected timeout in gst_bus_poll, looking for %d: %s", + tevent, descr); + break; + } else if (revent & events) { + continue; + } + g_critical + ("Unexpected message received of type %d, '%s', looking for %d: %s", + revent, gst_message_type_get_name (revent), tevent, descr); + } + +done: + gst_element_set_state (pipe, GST_STATE_NULL); + gst_object_unref (pipe); +} + +GST_START_TEST (test_libavcodec_locks) +{ + gchar *sink[NUM_SINKS + 1], *s, *sinks; + gint i; + + for (i = 0; i < NUM_SINKS; i++) + sink[i] = + g_strdup_printf + (" t.src_%u ! queue ! avenc_mpeg4 ! avdec_mpeg4 ! fakesink sync=true", + i); + + sink[NUM_SINKS] = NULL; + + sinks = g_strjoinv (" ", sink); + + s = g_strdup_printf + ("videotestsrc ! video/x-raw,format=(string)I420,width=320,height=240,framerate=(fraction)10/1 ! tee name=t %s", + sinks); + + run_pipeline (setup_pipeline (s), s, + GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING), + GST_MESSAGE_UNKNOWN); + g_free (s); + + for (i = 0; i < NUM_SINKS; i++) + g_free (sink[i]); + g_free (sinks); +} + +GST_END_TEST; + +static Suite * +simple_launch_lines_suite (void) +{ + gint timeout = 0; + + Suite *s = suite_create ("Pipelines"); + TCase *tc_chain = tcase_create ("linear"); + + if (g_getenv ("CK_DEFAULT_TIMEOUT")) + timeout = atoi (g_getenv ("CK_DEFAULT_TIMEOUT")); + + if (timeout == 0) + timeout = 3; + + /* set multiple of default timeout (random magic value) */ + tcase_set_timeout (tc_chain, timeout * 12); + + suite_add_tcase (s, tc_chain); + +#ifndef GST_DISABLE_PARSE + /* only run this if we haven't been configured with --disable-encoders */ + if (gst_registry_check_feature_version (gst_registry_get (), "avenc_mpeg4", + GST_VERSION_MAJOR, GST_VERSION_MINOR, 0)) { + tcase_add_test (tc_chain, test_libavcodec_locks); + } else { + g_print ("******* Skipping libavcodec_locks test, no encoder available\n"); + } +#endif + + return s; +} + +GST_CHECK_MAIN (simple_launch_lines); diff --git a/subprojects/gst-libav/tests/check/generic/plugin-test.c b/subprojects/gst-libav/tests/check/generic/plugin-test.c new file mode 100644 index 0000000000..53831d249b --- /dev/null +++ b/subprojects/gst-libav/tests/check/generic/plugin-test.c @@ -0,0 +1,98 @@ +/* GStreamer + * Copyright (C) 2009 Jan Schmidt <thaytan@noraisin.net> + * + * Test that the FFmpeg plugin is loadable, and not broken in some stupid + * way. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + + +#include <gst/check/gstcheck.h> +#include <stdlib.h> + +GST_START_TEST (test_libav_plugin) +{ + GstPlugin *plugin = gst_plugin_load_by_name ("libav"); + + fail_if (plugin == NULL, "Could not load FFmpeg plugin"); + + gst_object_unref (plugin); + +} + +GST_END_TEST; + +GST_START_TEST (test_libav_update_reg) +{ + GstElement *encoder, *muxer, *decoder; + + /* Ask for elements the first time */ + encoder = gst_element_factory_make ("avenc_mpeg2video", "sink"); + GST_DEBUG ("Creating element avenc_mpeg2video %p", encoder); + fail_unless (encoder != NULL); + + decoder = gst_element_factory_make ("avdec_mpeg2video", "sink"); + GST_DEBUG ("Creating element avdec_mpeg2video %p", decoder); + fail_unless (decoder != NULL); + + muxer = gst_element_factory_make ("avmux_dvd", "sink"); + GST_DEBUG ("Creating element avmux_dvd %p", muxer); + fail_unless (muxer != NULL); + + gst_object_unref (encoder); + gst_object_unref (decoder); + gst_object_unref (muxer); + + GST_DEBUG ("calls gst_update_registry"); + gst_update_registry (); + + /* Ask for elements the second time */ + + encoder = gst_element_factory_make ("avenc_mpeg2video", "sink"); + GST_DEBUG ("Creating element avenc_mpeg2video %p", encoder); + fail_unless (encoder != NULL); + + decoder = gst_element_factory_make ("avdec_mpeg2video", "sink"); + GST_DEBUG ("Creating element avdec_mpeg2video %p", decoder); + fail_unless (decoder != NULL); + + muxer = gst_element_factory_make ("avmux_dvd", "sink"); + GST_DEBUG ("Creating element avmux_dvd %p", muxer); + fail_unless (muxer != NULL); + + gst_object_unref (encoder); + gst_object_unref (decoder); + gst_object_unref (muxer); +} + +GST_END_TEST; + +static Suite * +plugin_test_suite (void) +{ + Suite *s = suite_create ("Plugin"); + TCase *tc_chain = tcase_create ("existence"); + + suite_add_tcase (s, tc_chain); + + tcase_add_test (tc_chain, test_libav_plugin); + tcase_add_test (tc_chain, test_libav_update_reg); + + return s; +} + +GST_CHECK_MAIN (plugin_test); diff --git a/subprojects/gst-libav/tests/check/gst-libav.supp b/subprojects/gst-libav/tests/check/gst-libav.supp new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/subprojects/gst-libav/tests/check/gst-libav.supp diff --git a/subprojects/gst-libav/tests/check/meson.build b/subprojects/gst-libav/tests/check/meson.build new file mode 100644 index 0000000000..a967f002cc --- /dev/null +++ b/subprojects/gst-libav/tests/check/meson.build @@ -0,0 +1,60 @@ +# name, condition when to skip the test and extra dependencies +libav_tests = [ + [ 'elements/avaudenc' ], + [ 'elements/avdec_adpcm' ], + [ 'elements/avdemux_ape' ], + [ 'elements/avvidenc' ], + [ 'generic/libavcodec-locking' ], + [ 'generic/plugin-test' ] +] + +test_defines = [ + '-UG_DISABLE_ASSERT', + '-UG_DISABLE_CAST_CHECKS', + '-DGST_CHECK_TEST_ENVIRONMENT_BEACON="GST_PLUGIN_LOADING_WHITELIST"', + '-DGST_TEST_FILES_PATH="' + meson.current_source_dir() + '/../files"', + '-DGST_USE_UNSTABLE_API', +] + +pluginsdirs = [] +if gst_dep.type_name() == 'pkgconfig' + pbase = dependency('gstreamer-plugins-base-' + api_version, required: true) + pluginsdirs = [gst_dep.get_pkgconfig_variable('pluginsdir'), + pbase.get_pkgconfig_variable('pluginsdir')] + gst_plugin_scanner_dir = gst_dep.get_pkgconfig_variable('pluginscannerdir') +else + gst_plugin_scanner_dir = subproject('gstreamer').get_variable('gst_scanner_dir') +endif +gst_plugin_scanner_path = join_paths(gst_plugin_scanner_dir, 'gst-plugin-scanner') + +# FIXME: check, also + PTHREAD_CFLAGS +test_deps = [gst_dep, gstbase_dep, gstcheck_dep, gstaudio_dep, + gstvideo_dep, gstpbutils_dep] + +# FIXME: add valgrind suppression common/gst.supp gst-libav.supp +foreach t : libav_tests + fname = '@0@.c'.format(t.get(0)) + test_name = t.get(0).underscorify() + extra_sources = t.get(3, [ ]) + extra_deps = t.get(2, [ ]) + skip_test = t.get(1, false) + if not skip_test + env = environment() + env.set('GST_PLUGIN_SYSTEM_PATH_1_0', '') + env.set('CK_DEFAULT_TIMEOUT', '20') + env.set('GST_PLUGIN_LOADING_WHITELIST', 'gstreamer', 'gst-plugins-base', + 'gst-libav@' + meson.build_root()) + env.set('GST_PLUGIN_PATH_1_0', [meson.build_root()] + pluginsdirs) + env.set('GSETTINGS_BACKEND', 'memory') + + env.set('GST_REGISTRY', join_paths(meson.current_build_dir(), '@0@.registry'.format(test_name))) + env.set('GST_PLUGIN_SCANNER_1_0', gst_plugin_scanner_path) + exe = executable(test_name, fname, extra_sources, + include_directories : [configinc], + c_args : ['-DHAVE_CONFIG_H=1' ] + test_defines, + dependencies : [libm] + test_deps + extra_deps, + ) + test(test_name, exe, env: env, timeout: 3 * 60) + endif +endforeach + |