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
This commit is contained in:
maroy 2005-07-03 15:11:23 +00:00
parent 0459fd787b
commit 239ff252fc
6 changed files with 159 additions and 12 deletions

View file

@ -21,7 +21,7 @@
# #
# #
# Author : $Author: maroy $ # 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 $ # Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/playlistExecutor/etc/Makefile.in,v $
# #
# @configure_input@ # @configure_input@
@ -136,7 +136,7 @@ TEST_RUNNER_OBJS = ${TMP_DIR}/TestRunner.o \
TEST_RUNNER_LIBS = -l${PLAYLIST_EXECUTOR_LIB} -l${CORE_LIB} \ TEST_RUNNER_LIBS = -l${PLAYLIST_EXECUTOR_LIB} -l${CORE_LIB} \
-l${GSTREAMER_ELEMENTS_LIB} \ -l${GSTREAMER_ELEMENTS_LIB} \
${TAGLIB_LIBS} \ ${TAGLIB_LIBS} \
-lcppunit -ldl -lm -lxmlrpc++ -lboost_date_time-gcc -lcppunit -ldl -lm -lxmlrpc++
TWOTEST_RUNNER_OBJS = ${TMP_DIR}/TestRunner.o \ TWOTEST_RUNNER_OBJS = ${TMP_DIR}/TestRunner.o \
${TMP_DIR}/TwoGstreamerPlayersTest.o ${TMP_DIR}/TwoGstreamerPlayersTest.o

View file

@ -22,7 +22,7 @@
Author : $Author: maroy $ 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 $ 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, "error", G_CALLBACK(errorHandler), this);
g_signal_connect(pipeline, "state-change", G_CALLBACK(stateChange), 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); setAudioDevice(audioDevice);
gst_bin_add(GST_BIN(pipeline), audiosink); 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 * Specify which file to play
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
@ -231,6 +245,9 @@ GstreamerPlayer :: open(const std::string fileUrl)
throw (std::invalid_argument) throw (std::invalid_argument)
{ {
std::string filePath; std::string filePath;
GstElement * pipe;
GstElement * fakesink;
gint64 position;
if (isOpened()) { if (isOpened()) {
close(); close();
@ -256,8 +273,35 @@ GstreamerPlayer :: open(const std::string fileUrl)
throw std::invalid_argument(std::string("can't open URL ") + 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_element_link(decoder, audiosink);
gst_bin_add_many(GST_BIN(pipeline), filesrc, decoder, audiosink, NULL); 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_element_set_state(pipeline, GST_STATE_PAUSED);
gst_bin_sync_children_state(GST_BIN(pipeline)); gst_bin_sync_children_state(GST_BIN(pipeline));

View file

@ -22,7 +22,7 @@
Author : $Author: maroy $ 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 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/playlistExecutor/src/GstreamerPlayer.h,v $
------------------------------------------------------------------------------*/ ------------------------------------------------------------------------------*/
@ -86,7 +86,7 @@ using namespace LiveSupport::Core;
* </code></pre> * </code></pre>
* *
* @author $Author: maroy $ * @author $Author: maroy $
* @version $Revision: 1.5 $ * @version $Revision: 1.6 $
*/ */
class GstreamerPlayer : virtual public Configurable, class GstreamerPlayer : virtual public Configurable,
virtual public AudioPlayerInterface virtual public AudioPlayerInterface
@ -178,6 +178,18 @@ class GstreamerPlayer : virtual public Configurable,
gpointer self) gpointer self)
throw (); 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. * Send the onStop event to all attached listeners.
*/ */

View file

@ -22,7 +22,7 @@
Author : $Author: maroy $ 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 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/playlistExecutor/src/GstreamerPlayerTest.cxx,v $
------------------------------------------------------------------------------*/ ------------------------------------------------------------------------------*/
@ -432,3 +432,70 @@ GstreamerPlayerTest :: eventListenerTest(void)
player->deInitialize(); 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<ptime>::Ref start;
Ptr<ptime>::Ref end;
Ptr<time_duration>::Ref openTime;
Ptr<time_duration>::Ref startTime;
Ptr<time_duration>::Ref stopTime;
Ptr<time_duration>::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();
}

View file

@ -21,8 +21,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Author : $Author: fgerlits $ Author : $Author: maroy $
Version : $Revision: 1.5 $ Version : $Revision: 1.6 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/playlistExecutor/src/GstreamerPlayerTest.h,v $ 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. * Unit test for the GstreamerPlayer class.
* *
* @author $Author: fgerlits $ * @author $Author: maroy $
* @version $Revision: 1.5 $ * @version $Revision: 1.6 $
* @see GstreamerPlayer * @see GstreamerPlayer
*/ */
class GstreamerPlayerTest : public CPPUNIT_NS::TestFixture class GstreamerPlayerTest : public CPPUNIT_NS::TestFixture
@ -72,6 +72,7 @@ class GstreamerPlayerTest : public CPPUNIT_NS::TestFixture
CPPUNIT_TEST(checkErrorConditions); CPPUNIT_TEST(checkErrorConditions);
CPPUNIT_TEST(eventListenerAttachTest); CPPUNIT_TEST(eventListenerAttachTest);
CPPUNIT_TEST(eventListenerTest); CPPUNIT_TEST(eventListenerTest);
CPPUNIT_TEST(openTimeTest);
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
private: private:
@ -81,6 +82,16 @@ class GstreamerPlayerTest : public CPPUNIT_NS::TestFixture
*/ */
Ptr<GstreamerPlayer>::Ref player; Ptr<GstreamerPlayer>::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: protected:
@ -148,6 +159,14 @@ class GstreamerPlayerTest : public CPPUNIT_NS::TestFixture
void void
eventListenerTest(void) throw (CPPUNIT_NS::Exception); 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: public:

View file

@ -22,7 +22,7 @@
Author : $Author: maroy $ 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 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/playlistExecutor/src/TestRunner.cxx,v $
------------------------------------------------------------------------------*/ ------------------------------------------------------------------------------*/
@ -47,6 +47,8 @@
#include <fstream> #include <fstream>
#include <gst/gst.h>
#include <cppunit/BriefTestProgressListener.h> #include <cppunit/BriefTestProgressListener.h>
#include <cppunit/CompilerOutputter.h> #include <cppunit/CompilerOutputter.h>
#include <cppunit/XmlOutputter.h> #include <cppunit/XmlOutputter.h>
@ -144,6 +146,9 @@ int
main( int argc, main( int argc,
char * argv[] ) throw () char * argv[] ) throw ()
{ {
// initialize the gst parameters
gst_init(&argc, &argv);
if (!processArguments(argc, argv)) { if (!processArguments(argc, argv)) {
return 0; return 0;
} }