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:
parent
0459fd787b
commit
239ff252fc
6 changed files with 159 additions and 12 deletions
|
@ -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
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
|
@ -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:
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue