From 239ff252fc2eca43ed773fc21fa1c32e3904bbc7 Mon Sep 17 00:00:00 2001 From: maroy Date: Sun, 3 Jul 2005 15:11:23 +0000 Subject: [PATCH] moved all gstreamer pipeline initialization to the open() call, thus calling start() will be fast. opening can be still slow though (like 10 secs for some SMIL files). this is in response to issue #1229, see http://bugs.campware.org/view.php?id=1229 --- .../modules/playlistExecutor/etc/Makefile.in | 4 +- .../playlistExecutor/src/GstreamerPlayer.cxx | 48 ++++++++++++- .../playlistExecutor/src/GstreamerPlayer.h | 16 ++++- .../src/GstreamerPlayerTest.cxx | 69 ++++++++++++++++++- .../src/GstreamerPlayerTest.h | 27 ++++++-- .../playlistExecutor/src/TestRunner.cxx | 7 +- 6 files changed, 159 insertions(+), 12 deletions(-) diff --git a/livesupport/modules/playlistExecutor/etc/Makefile.in b/livesupport/modules/playlistExecutor/etc/Makefile.in index f48ecfea9..6c124e14f 100644 --- a/livesupport/modules/playlistExecutor/etc/Makefile.in +++ b/livesupport/modules/playlistExecutor/etc/Makefile.in @@ -21,7 +21,7 @@ # # # Author : $Author: maroy $ -# Version : $Revision: 1.17 $ +# Version : $Revision: 1.18 $ # Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/playlistExecutor/etc/Makefile.in,v $ # # @configure_input@ @@ -136,7 +136,7 @@ TEST_RUNNER_OBJS = ${TMP_DIR}/TestRunner.o \ TEST_RUNNER_LIBS = -l${PLAYLIST_EXECUTOR_LIB} -l${CORE_LIB} \ -l${GSTREAMER_ELEMENTS_LIB} \ ${TAGLIB_LIBS} \ - -lcppunit -ldl -lm -lxmlrpc++ + -lboost_date_time-gcc -lcppunit -ldl -lm -lxmlrpc++ TWOTEST_RUNNER_OBJS = ${TMP_DIR}/TestRunner.o \ ${TMP_DIR}/TwoGstreamerPlayersTest.o diff --git a/livesupport/modules/playlistExecutor/src/GstreamerPlayer.cxx b/livesupport/modules/playlistExecutor/src/GstreamerPlayer.cxx index b25693b7a..38420daa6 100644 --- a/livesupport/modules/playlistExecutor/src/GstreamerPlayer.cxx +++ b/livesupport/modules/playlistExecutor/src/GstreamerPlayer.cxx @@ -22,7 +22,7 @@ Author : $Author: maroy $ - Version : $Revision: 1.3 $ + Version : $Revision: 1.4 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/playlistExecutor/src/GstreamerPlayer.cxx,v $ ------------------------------------------------------------------------------*/ @@ -109,7 +109,7 @@ GstreamerPlayer :: initialize(void) throw (std::exception) g_signal_connect(pipeline, "error", G_CALLBACK(errorHandler), this); g_signal_connect(pipeline, "state-change", G_CALLBACK(stateChange), this); - audiosink = gst_element_factory_make("alsasink", "audiosink"); + audiosink = gst_element_factory_make("alsasink", "alsasink"); setAudioDevice(audioDevice); gst_bin_add(GST_BIN(pipeline), audiosink); @@ -223,6 +223,20 @@ GstreamerPlayer :: fireOnStopEvent(void) throw () } +/*------------------------------------------------------------------------------ + * An EOS event handler, that will put the pipeline to EOS as well. + *----------------------------------------------------------------------------*/ +void +GstreamerPlayer :: eosEventHandler(GstElement * element, + gpointer self) + throw () +{ + GstreamerPlayer * player = (GstreamerPlayer*) self; + + gst_element_set_eos(player->pipeline); +} + + /*------------------------------------------------------------------------------ * Specify which file to play *----------------------------------------------------------------------------*/ @@ -231,6 +245,9 @@ GstreamerPlayer :: open(const std::string fileUrl) throw (std::invalid_argument) { std::string filePath; + GstElement * pipe; + GstElement * fakesink; + gint64 position; if (isOpened()) { close(); @@ -256,8 +273,35 @@ GstreamerPlayer :: open(const std::string fileUrl) throw std::invalid_argument(std::string("can't open URL ") + fileUrl); } + // connect the decoder unto a fakesink, and iterate on it until the + // first bytes come out. this is to make sure that _really_ all + // initialiation is done at opening + pipe = gst_pipeline_new("pipe"); + fakesink = gst_element_factory_make("fakesink", "fakesink"); + g_object_ref(G_OBJECT(filesrc)); + g_object_ref(G_OBJECT(decoder)); + gst_element_link_many(decoder, fakesink, NULL); + gst_bin_add_many(GST_BIN(pipe), filesrc, decoder, fakesink, NULL); + + gst_element_set_state(pipe, GST_STATE_PAUSED); + gst_element_set_state(pipe, GST_STATE_PLAYING); + + position = 0LL; + while (position == 0LL && gst_bin_iterate(GST_BIN(pipe))) { + GstFormat format = GST_FORMAT_DEFAULT; + gst_element_query(fakesink, GST_QUERY_POSITION, &format, &position); + } + + gst_element_set_state(pipe, GST_STATE_PAUSED); + gst_bin_remove_many(GST_BIN(pipe), filesrc, decoder, NULL); + gst_element_unlink(decoder, fakesink); + gst_object_unref(GST_OBJECT(pipe)); + + // connect the decoder to the real audio sink gst_element_link(decoder, audiosink); gst_bin_add_many(GST_BIN(pipeline), filesrc, decoder, audiosink, NULL); + // connect the eos signal handler + g_signal_connect(decoder, "eos", G_CALLBACK(eosEventHandler), this); gst_element_set_state(pipeline, GST_STATE_PAUSED); gst_bin_sync_children_state(GST_BIN(pipeline)); diff --git a/livesupport/modules/playlistExecutor/src/GstreamerPlayer.h b/livesupport/modules/playlistExecutor/src/GstreamerPlayer.h index 60752da40..e15c05cdc 100644 --- a/livesupport/modules/playlistExecutor/src/GstreamerPlayer.h +++ b/livesupport/modules/playlistExecutor/src/GstreamerPlayer.h @@ -22,7 +22,7 @@ Author : $Author: maroy $ - Version : $Revision: 1.5 $ + Version : $Revision: 1.6 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/playlistExecutor/src/GstreamerPlayer.h,v $ ------------------------------------------------------------------------------*/ @@ -86,7 +86,7 @@ using namespace LiveSupport::Core; * * * @author $Author: maroy $ - * @version $Revision: 1.5 $ + * @version $Revision: 1.6 $ */ class GstreamerPlayer : virtual public Configurable, virtual public AudioPlayerInterface @@ -178,6 +178,18 @@ class GstreamerPlayer : virtual public Configurable, gpointer self) throw (); + /** + * An end-of-stream event handler, that will notify our pipeline, + * that it's all over. + * + * @param element the element emitting the eos signal + * @param self a pointer to the associated GstreamerPlayer object. + */ + static void + eosEventHandler(GstElement * element, + gpointer self) + throw (); + /** * Send the onStop event to all attached listeners. */ diff --git a/livesupport/modules/playlistExecutor/src/GstreamerPlayerTest.cxx b/livesupport/modules/playlistExecutor/src/GstreamerPlayerTest.cxx index bc350b4c7..4bcf8fcfd 100644 --- a/livesupport/modules/playlistExecutor/src/GstreamerPlayerTest.cxx +++ b/livesupport/modules/playlistExecutor/src/GstreamerPlayerTest.cxx @@ -22,7 +22,7 @@ Author : $Author: maroy $ - Version : $Revision: 1.4 $ + Version : $Revision: 1.5 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/playlistExecutor/src/GstreamerPlayerTest.cxx,v $ ------------------------------------------------------------------------------*/ @@ -432,3 +432,70 @@ GstreamerPlayerTest :: eventListenerTest(void) player->deInitialize(); } + +/*------------------------------------------------------------------------------ + * Time how long it takes to open, play and close files. + *----------------------------------------------------------------------------*/ +void +GstreamerPlayerTest :: timeSteps(const std::string fileName) + throw (CPPUNIT_NS::Exception) +{ + Ptr::Ref start; + Ptr::Ref end; + Ptr::Ref openTime; + Ptr::Ref startTime; + Ptr::Ref stopTime; + Ptr::Ref closeTime; + + start = TimeConversion::now(); + try { + player->open(fileName); + } catch (std::invalid_argument &e) { + CPPUNIT_FAIL(e.what()); + } + end = TimeConversion::now(); + openTime.reset(new time_duration(*end - *start)); + + CPPUNIT_ASSERT(!player->isPlaying()); + start = TimeConversion::now(); + CPPUNIT_ASSERT_NO_THROW( + player->start(); + ); + end = TimeConversion::now(); + startTime.reset(new time_duration(*end - *start)); + + CPPUNIT_ASSERT(player->isPlaying()); + + start = TimeConversion::now(); + player->stop(); + end = TimeConversion::now(); + stopTime.reset(new time_duration(*end - *start)); + + CPPUNIT_ASSERT(!player->isPlaying()); + + start = TimeConversion::now(); + player->close(); + end = TimeConversion::now(); + closeTime.reset(new time_duration(*end - *start)); + + // TODO: somehow assert on the time values +} + + +/*------------------------------------------------------------------------------ + * Test how long it takes to open and play files. + *----------------------------------------------------------------------------*/ +void +GstreamerPlayerTest :: openTimeTest(void) + throw (CPPUNIT_NS::Exception) +{ + player->initialize(); + + timeSteps("file:var/test.mp3"); + + timeSteps("file:var/simpleSmil.smil"); + + timeSteps("file:var/sequentialSmil.smil"); + + player->deInitialize(); +} diff --git a/livesupport/modules/playlistExecutor/src/GstreamerPlayerTest.h b/livesupport/modules/playlistExecutor/src/GstreamerPlayerTest.h index c67704a6a..ae2adb539 100644 --- a/livesupport/modules/playlistExecutor/src/GstreamerPlayerTest.h +++ b/livesupport/modules/playlistExecutor/src/GstreamerPlayerTest.h @@ -21,8 +21,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Author : $Author: fgerlits $ - Version : $Revision: 1.5 $ + Author : $Author: maroy $ + Version : $Revision: 1.6 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/playlistExecutor/src/GstreamerPlayerTest.h,v $ ------------------------------------------------------------------------------*/ @@ -57,8 +57,8 @@ namespace PlaylistExecutor { /** * Unit test for the GstreamerPlayer class. * - * @author $Author: fgerlits $ - * @version $Revision: 1.5 $ + * @author $Author: maroy $ + * @version $Revision: 1.6 $ * @see GstreamerPlayer */ class GstreamerPlayerTest : public CPPUNIT_NS::TestFixture @@ -72,6 +72,7 @@ class GstreamerPlayerTest : public CPPUNIT_NS::TestFixture CPPUNIT_TEST(checkErrorConditions); CPPUNIT_TEST(eventListenerAttachTest); CPPUNIT_TEST(eventListenerTest); + CPPUNIT_TEST(openTimeTest); CPPUNIT_TEST_SUITE_END(); private: @@ -81,6 +82,16 @@ class GstreamerPlayerTest : public CPPUNIT_NS::TestFixture */ Ptr::Ref player; + /** + * Time how long it takes to open, play, stop and close files. + * + * @param fileName the name of the file to take a look at. + * @exception CPPUNIT_NS::Exception on test failures. + */ + void + timeSteps(const std::string fileName) + throw (CPPUNIT_NS::Exception); + protected: @@ -148,6 +159,14 @@ class GstreamerPlayerTest : public CPPUNIT_NS::TestFixture void eventListenerTest(void) throw (CPPUNIT_NS::Exception); + /** + * Test how long it takes to open and play files. + * + * @exception CPPUNIT_NS::Exception on test failures. + */ + void + openTimeTest(void) throw (CPPUNIT_NS::Exception); + public: diff --git a/livesupport/modules/playlistExecutor/src/TestRunner.cxx b/livesupport/modules/playlistExecutor/src/TestRunner.cxx index 0ab739cdc..64b3e5792 100644 --- a/livesupport/modules/playlistExecutor/src/TestRunner.cxx +++ b/livesupport/modules/playlistExecutor/src/TestRunner.cxx @@ -22,7 +22,7 @@ Author : $Author: maroy $ - Version : $Revision: 1.1 $ + Version : $Revision: 1.2 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/playlistExecutor/src/TestRunner.cxx,v $ ------------------------------------------------------------------------------*/ @@ -47,6 +47,8 @@ #include +#include + #include #include #include @@ -144,6 +146,9 @@ int main( int argc, char * argv[] ) throw () { + // initialize the gst parameters + gst_init(&argc, &argv); + if (!processArguments(argc, argv)) { return 0; }