diff --git a/tests/check/elements/decodebin2.c b/tests/check/elements/decodebin2.c index 84cf4054c2..8eb47981e6 100644 --- a/tests/check/elements/decodebin2.c +++ b/tests/check/elements/decodebin2.c @@ -1,6 +1,7 @@ /* GStreamer unit tests for decodebin2 * * Copyright (C) 2006 Tim-Philipp Müller + * Copyright (C) 2011 Hewlett-Packard Development Company, L.P. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -23,6 +24,7 @@ #endif #include +#include #include static const gchar dummytext[] = @@ -187,6 +189,177 @@ GST_START_TEST (test_reuse_without_decoders) GST_END_TEST; +/* Fake mp3 parser for test */ +typedef GstBaseParse TestMpegAudioParse; +typedef GstBaseParseClass TestMpegAudioParseClass; + +static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("audio/mpeg, mpegversion=1, layer=[1,3], parsed=(b)true") + ); + +static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("audio/mpeg, mpegversion=1, parsed=(bool) { false, true }") + ); + +static GType test_mpeg_audio_parse_get_type (void); +static gboolean test_mpeg_audio_parse_start (GstBaseParse * parse); +static gboolean test_mpeg_audio_parse_stop (GstBaseParse * parse); +static gboolean test_mpeg_audio_parse_check_valid_frame (GstBaseParse * parse, + GstBaseParseFrame * frame, guint * size, gint * skipsize); +static GstFlowReturn test_mpeg_audio_parse_parse_frame (GstBaseParse * parse, + GstBaseParseFrame * frame); + +GST_BOILERPLATE (TestMpegAudioParse, test_mpeg_audio_parse, GstBaseParse, + GST_TYPE_BASE_PARSE); + +static void +test_mpeg_audio_parse_base_init (gpointer klass) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&sink_template)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&src_template)); + + gst_element_class_set_details_simple (element_class, "MPEG1 Audio Parser", + "Codec/Parser/Audio", "Pretends to parse mpeg1 audio stream", + "Foo Bar "); +} + +static void +test_mpeg_audio_parse_class_init (TestMpegAudioParseClass * klass) +{ + GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass); + + parse_class->start = test_mpeg_audio_parse_start; + parse_class->stop = test_mpeg_audio_parse_stop; + parse_class->check_valid_frame = test_mpeg_audio_parse_check_valid_frame; + parse_class->parse_frame = test_mpeg_audio_parse_parse_frame; +} + +static gint num_parse_instances = 0; + +static void +test_mpeg_audio_parse_init (TestMpegAudioParse * mp3parse, + TestMpegAudioParseClass * klass) +{ + /* catch decodebin plugging parsers in a loop early */ + fail_unless (++num_parse_instances < 10); +} + +static gboolean +test_mpeg_audio_parse_start (GstBaseParse * parse) +{ + gst_base_parse_set_min_frame_size (parse, 6); + return TRUE; +} + +static gboolean +test_mpeg_audio_parse_stop (GstBaseParse * parse) +{ + return TRUE; +} + +static gboolean +test_mpeg_audio_parse_check_valid_frame (GstBaseParse * parse, + GstBaseParseFrame * frame, guint * framesize, gint * skipsize) +{ + const guint8 *data = GST_BUFFER_DATA (frame->buffer); + + if ((GST_READ_UINT16_BE (data) & 0xffe0) == 0xffe0) { + /* this framesize is hard-coded for ../test.mp3 */ + *framesize = 1045; + return TRUE; + } else { + *skipsize = 1; + return FALSE; + } +} + +static GstFlowReturn +test_mpeg_audio_parse_parse_frame (GstBaseParse * parse, + GstBaseParseFrame * frame) +{ + if (GST_BUFFER_OFFSET (frame->buffer) == 0) { + GstCaps *caps; + + caps = gst_caps_new_simple ("audio/mpeg", "mpegversion", G_TYPE_INT, 1, + "mpegaudioversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 3, + "rate", G_TYPE_INT, 44100, "channels", G_TYPE_INT, 2, NULL); + gst_buffer_set_caps (frame->buffer, caps); + gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (parse), caps); + gst_caps_unref (caps); + } + return GST_FLOW_OK; +} + +static gboolean +plugin_init (GstPlugin * plugin) +{ + return gst_element_register (plugin, "testmpegaudioparse", GST_RANK_NONE, + test_mpeg_audio_parse_get_type ()); +} + +GST_START_TEST (test_mp3_parser_loop) +{ + GstStateChangeReturn sret; + GstPluginFeature *feature; + GstMessage *msg; + GstElement *pipe, *src, *dec; + gchar *path; + + num_parse_instances = 0; + + gst_plugin_register_static (GST_VERSION_MAJOR, GST_VERSION_MINOR, + "fakemp3parse", "fakemp3parse", plugin_init, VERSION, "LGPL", + "gst-plugins-base", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN); + + feature = gst_default_registry_find_feature ("testmpegaudioparse", + GST_TYPE_ELEMENT_FACTORY); + + gst_plugin_feature_set_rank (feature, GST_RANK_PRIMARY + 100); + + pipe = gst_pipeline_new (NULL); + + src = gst_element_factory_make ("filesrc", NULL); + fail_unless (src != NULL); + + path = g_build_filename (GST_TEST_FILES_PATH, "test.mp3", NULL); + g_object_set (src, "location", path, NULL); + g_free (path); + + dec = gst_element_factory_make ("decodebin2", NULL); + fail_unless (dec != NULL); + + gst_bin_add_many (GST_BIN (pipe), src, dec, NULL); + gst_element_link_many (src, dec, NULL); + + sret = gst_element_set_state (pipe, GST_STATE_PLAYING); + fail_unless_equals_int (sret, GST_STATE_CHANGE_ASYNC); + + /* wait for unlinked error */ + msg = gst_bus_timed_pop_filtered (GST_ELEMENT_BUS (pipe), + GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR); + gst_message_unref (msg); + + gst_element_set_state (pipe, GST_STATE_NULL); + gst_object_unref (pipe); + + /* make sure out parser got plugged at all though */ + fail_unless_equals_int (num_parse_instances, 1); + + /* don't want to interfere with any other of the other tests */ + gst_plugin_feature_set_rank (feature, GST_RANK_NONE); + gst_object_unref (feature); +} + +GST_END_TEST; + static Suite * decodebin2_suite (void) { @@ -196,6 +369,7 @@ decodebin2_suite (void) suite_add_tcase (s, tc_chain); tcase_add_test (tc_chain, test_text_plain_streams); tcase_add_test (tc_chain, test_reuse_without_decoders); + tcase_add_test (tc_chain, test_mp3_parser_loop); return s; }