From b3a39daed618e54d7374a39bd70b732e22cd467f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Wed, 6 Jul 2011 19:40:48 +0100 Subject: [PATCH] tests: add decodebin1 test for parser autoplugging Make sure decodebin1 doesn't try to plug the same parser twice in a row (so we can change all parsers to accept parsed input as well without breaking applications still using the old decodebin1 element). --- tests/check/elements/decodebin.c | 174 +++++++++++++++++++++++++++++++ tests/files/Makefile.am | 3 +- tests/files/test.mp3 | Bin 0 -> 3135 bytes 3 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 tests/files/test.mp3 diff --git a/tests/check/elements/decodebin.c b/tests/check/elements/decodebin.c index eb6f38a4e6..d5d327e95d 100644 --- a/tests/check/elements/decodebin.c +++ b/tests/check/elements/decodebin.c @@ -1,6 +1,7 @@ /* GStreamer unit tests for decodebin * * 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[] = @@ -184,6 +186,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 ("decodebin", 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 * decodebin_suite (void) { @@ -193,6 +366,7 @@ decodebin_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; } diff --git a/tests/files/Makefile.am b/tests/files/Makefile.am index ca997a2a07..dfe968acbd 100644 --- a/tests/files/Makefile.am +++ b/tests/files/Makefile.am @@ -1,4 +1,5 @@ EXTRA_DIST = \ 623663.mts \ hls.m3u8 \ - partialframe.mjpeg + partialframe.mjpeg \ + test.mp3 diff --git a/tests/files/test.mp3 b/tests/files/test.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..304892c3cfd8703af65c45ca5fd917aa51cece90 GIT binary patch literal 3135 zcmeI!XON^N!)ug0qqk1TY{t5a>JMw_X&oo(CwwBP5`?)&iGm-l-g-tYbXzxUgRRlw)i zFZf)*KYc2e)s$6Gv*U=vn1$-Lb00e@$Q@vf5(8tXOSMr)+_r`jECmWuxle zlA)~~Edc##U`k4dg>Lco3hf>o4?g-$Yp!8DiLIBK$z10Ci>$}qK4Q<*o!X0mGR62 z)O^Rrrh%5#GaKY!->Vf>*$HLpzSG7Y=k_L^C0%>`o_S@v+5Y?6VAzbVmM`&5X;q~o za&7)cg_mHN0v3sreksx2*yOB1Am>az=owpJFc|3iFaJQY!R)_vLOQJNvMik_KS7!uhZT%ns@cU{pY_3tn<#!02{WgZlX zXk!WTn+N9u#FKaNqJ)|seVId}aQg>d@y7f}wvW0q0sX?U)w|dx9X2*OwXzgSd%Dwm zEZIMKqNVVgC8Z+FKPfFR(c}s~%%oRh+$n`r#^yGkO-xv%Yp6lz9b=;8{{Uj~X{|Wi{YIvPS#lr()h^CmD{)+p z+MXVhQv*f#foYofP<_(c1)}?KB%17Zyn^k17PrGZVrY8C4vwqdbScuL=zHtJE(=(^ z`KAC`%9tcHp}>$CWkt?hs-q5dX7a{y#tY=u74H3ex(|P5MLMlX>3e^Y)7}*s;`0(S zu&L}l#;<8~$(Ko2AeC+zwv1$LBU1HP{ViQ-s}~NfSkhe~#9>m~ipqUkMzg(&pm6iU zReLhGuGXabj=1_E8^5tQY`Xr`R-vA%98OX)p2yit5u@27&Ji#C_(f{FAaly)^^>Iz zh#eV3tGu7W$6*3}h zmee_`xP#cJ2PY1A+ZoaN*9+HaDVK=pfQn0ItngMEI1}#vCbF~%0=}no(;o7i<5Hg$ zxDdS50p;MKVpZYs2qxU<2F_bdY%>kf4v&Q@F{S+IWHa%I3B!vqmIc+p4(_F0?HGB$ z?>A%ct;T&qg7;-8=eZS-AIy^p5tnjiOha^iDiuj#KV-<#tD|Ep0zIPvT_G}jRZlg0 zus7F*ptrB3hE+sIqW_|(wu$$2$WOS1+)}+d^jQ7%z+zp^dV_qv{ux-OgwW zsx4NI!VxrHbY<=A^R>iG1bGB!^?*|c4F4)91n56m2ZlitNh5%HQE@TvR45BO=}a%y z&?$4nTdgsrz+cIy@*CcDjMS#76tCQ-Ln23a8&P}8uqTqnvDK20QBE;NB)48J)yG)V z-l}gkYvMK~vazJ33eA+_T%fgW+qgm>cDaPeiW>J1;r~ZQi z|6eF1X5W7UQGG(e3`}|R=~Ec){5J~T0MSH1cko2?f+g?7RojK^3Ln)Ksvngq=m^pn zrz1M-3I{_XplzW;g|Q5$y`I#dHA7xM<~71KK=voyC+gv|oNqp6?lyUt^K_s0p{zf5 zm^WI!=5BAt9|>S9U(~!Nto87}ya#JS~som#f*^wB5LmAtG=i&PKZ z#v|ne8PFx5sBC$X>5vKTh%mFmlHbm9lkl`nLMP;%XLcTZ(*KD|3&x+c>qKk6fy9u? zYr~KA&fEc4%#~H89>I}Y-C#0{=GD>-`)l`Be`UMrGG{CJOJdT72#4;kdQ4!# zXpJ|BvbOCD#rbHhBC>W6W(SyTDk1Bi$a53qVnbK%PMlx0ou z-HRfWwotH4Lj#EoB^W%sa2g^{4n#rjeycN@m^~_hH!BeyX3pjQvnl7nQSS5)duYKk zVOUDEi#!SXG@?X!2p zrg>KDRO!_9OhwL!ti`FTJZ+t`==W0Jgxn${zH~)J7Z`Sb0X`>f`<19IB~5;Nv;kX8 zjvS%ai(H!$lnQ76wn10|ekWbWNRkvPzIo>@N!1==e2%helUPO;7Z9Kr8Opa|fM<=w k