Added a preload() method, for speeding up SMIL playlist loading. The idea is to open the file that is likely to be played next already during playback of another file.

Code generally works, but some details still need to be worked out.
This commit is contained in:
mark 2006-11-21 22:27:59 +00:00
parent e3fbd34a58
commit f48c22f1c8
2 changed files with 87 additions and 5 deletions
campcaster/src/modules/playlistExecutor/src

View File

@ -278,6 +278,68 @@ GstreamerPlayer::newpadEventHandler(GstElement*, GstPad* pad, gboolean, gpointer
}
/*------------------------------------------------------------------------------
* Preload a file, to speed up the subsequent open() call.
*----------------------------------------------------------------------------*/
void
GstreamerPlayer :: preload(const std::string fileUrl)
throw (std::invalid_argument,
std::runtime_error)
{
DEBUG_BLOCK
const bool isSmil = fileUrl.substr(fileUrl.size()-5, fileUrl.size()) == ".smil" ? true : false;
if (!isSmil)
return;
debug() << "Preloading SMIL file: " << fileUrl << endl;
std::string filePath;
if (fileUrl.find("file://") == 0) {
filePath = fileUrl.substr(7, fileUrl.size());
}
else if (fileUrl.find("file:") == 0) {
filePath = fileUrl.substr(5, fileUrl.size());
}
else {
return;
}
if (!m_preloadUrl.empty()) {
g_object_unref(G_OBJECT(m_preloadFilesrc));
g_object_unref(G_OBJECT(m_preloadDecoder));
}
m_preloadFilesrc = gst_element_factory_make("filesrc", NULL);
gst_element_set(m_preloadFilesrc, "location", filePath.c_str(), NULL);
m_preloadDecoder = gst_element_factory_make("minimalaudiosmil", NULL);
GstElement* pipe = gst_pipeline_new("pipe");
GstElement* fakesink = gst_element_factory_make("fakesink", "fakesink");
g_object_ref(G_OBJECT(m_preloadFilesrc));
g_object_ref(G_OBJECT(m_preloadDecoder));
gst_element_link_many(m_preloadFilesrc, m_preloadDecoder, fakesink, NULL);
gst_bin_add_many(GST_BIN(pipe), m_preloadFilesrc, m_preloadDecoder, fakesink, NULL);
gst_element_set_state(pipe, GST_STATE_PLAYING);
gint64 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), m_preloadFilesrc, m_preloadDecoder, NULL);
gst_element_unlink(m_preloadFilesrc, fakesink);
gst_object_unref(GST_OBJECT(pipe));
m_preloadUrl = fileUrl;
}
/*------------------------------------------------------------------------------
* Specify which file to play
*----------------------------------------------------------------------------*/
@ -297,6 +359,8 @@ GstreamerPlayer :: open(const std::string fileUrl)
debug() << "Opening URL: " << fileUrl << endl;
preload(fileUrl);
std::string filePath;
if (fileUrl.find("file://") == 0) {
@ -311,8 +375,12 @@ GstreamerPlayer :: open(const std::string fileUrl)
const bool isSmil = fileUrl.substr(fileUrl.size()-5, fileUrl.size()) == ".smil" ? true : false;
m_filesrc = gst_element_factory_make("filesrc", "file-source");
gst_element_set(m_filesrc, "location", filePath.c_str(), NULL);
if ( m_preloadUrl != fileUrl ) {
m_filesrc = gst_element_factory_make("filesrc", "file-source");
gst_element_set(m_filesrc, "location", filePath.c_str(), NULL);
}
else
m_filesrc = m_preloadFilesrc;
// converts between different audio formats (e.g. bitrate)
m_audioconvert = gst_element_factory_make("audioconvert", NULL);
@ -324,9 +392,14 @@ GstreamerPlayer :: open(const std::string fileUrl)
// Therefore we instantiate it manually if the file has the .smil extension.
if (isSmil) {
debug() << "SMIL file detected." << endl;
m_decoder = gst_element_factory_make("minimalaudiosmil", NULL);
if (!m_decoder) error() << "Unable to create minimalaudiosmil element." << endl;
gst_element_link_many(m_filesrc, m_decoder, m_audioconvert, NULL);
if (m_preloadUrl != fileUrl) {
m_decoder = gst_element_factory_make("minimalaudiosmil", NULL);
gst_element_link_many(m_filesrc, m_decoder, m_audioconvert, NULL);
}
else {
m_decoder = m_preloadDecoder;
gst_element_link(m_decoder, m_audioconvert);
}
if (gst_element_get_parent(m_audiosink) == NULL)
gst_bin_add(GST_BIN(m_pipeline), m_audiosink);
}
@ -354,6 +427,8 @@ GstreamerPlayer :: open(const std::string fileUrl)
// the audio device (as it might be blocked by an other process
throw std::runtime_error("can't open audio device " + m_audioDevice);
}
m_preloadUrl.clear();
}

View File

@ -147,6 +147,10 @@ class GstreamerPlayer : virtual public Configurable,
*/
std::string m_audioDevice;
std::string m_preloadUrl;
GstElement * m_preloadFilesrc;
GstElement * m_preloadDecoder;
/**
* The type for the vector of listeners.
* Just a shorthand notation, to make reference to the type
@ -304,6 +308,9 @@ class GstreamerPlayer : virtual public Configurable,
setAudioDevice(const std::string &deviceName)
throw ();
virtual void
preload(const std::string fileUrl) throw (std::invalid_argument,
std::runtime_error);
/**
* Specify which audio resource to play.