[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-multimedia
Subject: Re: PATCH: proposed changes to KPlayObjectFactory/KPlayObjectCreator
From: Matthias Welwarsky <matze () stud ! fbi ! fh-darmstadt ! de>
Date: 2002-08-28 11:02:31
[Download RAW message or body]
[Attachment #2 (multipart/mixed)]
On Wednesday 28 August 2002 12:53, Matthias Welwarsky wrote:
> Hi,
>
> to give you some more fan service, I post two patches that implement the
> proposed patches in KPlayObjectFactory/KPlayObjectCreator, including a
> patch to kaboodles Engine so that you can see how the Interface is meant to
> be used.
>
> I know that there's quite some uglyness in this approach, namely that the
> PlayObject is not being created by KPlayObjectCreator::create(), so that
> you cannot immediately call "play" after create(), and I'm open to
> suggestions, but I really don't want to keep the current enter_loop()
> approach that opens the door for many, many bugs due to reentrancy.
>
> regards,
> matze
oops, forgot the patch :)
--
Matthias Welwarsky
Fachschaft Informatik FH Darmstadt
Email: matze@stud.fbi.fh-darmstadt.de
"all software sucks equally, but some software is more equal"
[" " (text/x-diff)]
Index: engine.cpp
===================================================================
RCS file: /home/kde/kdemultimedia/kaboodle/engine.cpp,v
retrieving revision 1.31
diff -u -3 -p -u -r1.31 engine.cpp
--- engine.cpp 2002/06/06 10:56:59 1.31
+++ engine.cpp 2002/08/28 10:44:49
@@ -55,6 +55,7 @@ class Kaboodle::Engine::EnginePrivate
public:
EnginePrivate()
: playobj(0)
+ , creator(0)
, dispatcher()
, server()
{
@@ -63,12 +64,15 @@ public:
~EnginePrivate()
{
delete playobj;
+ delete creator;
}
KPlayObject *playobj;
+ KPlayObjectCreator *creator;
KArtsDispatcher dispatcher;
KArtsServer server;
KURL file;
+ bool needPlaying;
};
Kaboodle::Engine::Engine(QObject *parent)
@@ -85,6 +89,8 @@ Kaboodle::Engine::~Engine()
bool Kaboodle::Engine::load(const KURL &file)
{
+ kdDebug() << "Engine::load " << file.url() << endl;
+
if(file.path().length())
{
d->file = file;
@@ -95,21 +101,65 @@ bool Kaboodle::Engine::load(const KURL &
bool Kaboodle::Engine::reload(void)
{
+ kdDebug() << "Engine::reload\n";
+
// Only You can prevent memory leaks
delete d->playobj;
d->playobj = 0;
+
+ delete d->creator;
+ d->creator = 0;
- KPlayObjectFactory factory(d->server.server());
- d->playobj = factory.createPlayObject(d->file, true);
+ d->creator = new KPlayObjectCreator(d->server.server());
+
+ connect(d->creator, SIGNAL(playObjectCreated(KPlayObject*)),
+ this, SLOT(attachPlayObject(KPlayObject*)));
+
+ bool result = d->creator->create(d->file, true);
m_needReload = false;
+ d->needPlaying = false;
- return !d->playobj->object().isNull();
+ return result;
+}
+
+void Kaboodle::Engine::attachPlayObject(KPlayObject* playObject)
+{
+ kdDebug() << "Engine::attachPlayObject\n";
+
+ if (d->playobj)
+ delete d->playobj;
+
+ d->playobj = playObject;
+
+ // check if it's alive
+ if (d->playobj->object().isNull())
+ return;
+
+ // the object just got created, so we assume it's idle;
+ if (d->needPlaying) {
+ d->needPlaying = false;
+ m_needReload = true;
+ d->playobj->play();
+ }
}
void Kaboodle::Engine::play()
{
- if(d->playobj && !d->playobj->object().isNull())
+ kdDebug() << "Engine::play\n";
+
+ if (!d->playobj) {
+ // there is no playobject yet, start to play when
+ // it got created.
+ d->needPlaying = true;
+ if (m_needReload)
+ reload();
+ return;
+ }
+
+ kdDebug() << "Engine::play " << d->playobj << endl;
+
+ if(!d->playobj->object().isNull())
{
switch(d->playobj->state())
{
@@ -117,7 +167,7 @@ void Kaboodle::Engine::play()
if (m_needReload)
reload();
m_needReload = true;
- d->playobj->play();
+ d->needPlaying = true;
break;
case Arts::posPaused:
d->playobj->play();
@@ -125,7 +175,7 @@ void Kaboodle::Engine::play()
default:
break;
}
- }
+ }
}
void Kaboodle::Engine::pause()
@@ -136,6 +186,8 @@ void Kaboodle::Engine::pause()
void Kaboodle::Engine::stop()
{
+// kdDebug() << "Engine::stop\n";
+
if(d->playobj && !d->playobj->object().isNull())
{
d->playobj->halt();
@@ -146,6 +198,9 @@ void Kaboodle::Engine::stop()
// pass time in msecs
void Kaboodle::Engine::seek(unsigned long msec)
{
+ if (!seekable())
+ return;
+
Arts::poTime t;
t.ms = (long) msec % 1000;
@@ -196,7 +251,7 @@ KMediaPlayer::Player::State Kaboodle::En
bool Kaboodle::Engine::seekable(void)
{
- if(!d->playobj) return false;
+ if(!d->playobj || d->playobj->object().isNull()) return false;
return d->playobj->object().capabilities() & Arts::capSeek;
}
@@ -206,3 +261,4 @@ Arts::PlayObject Kaboodle::Engine::playO
}
#include "engine.moc"
+
Index: engine.h
===================================================================
RCS file: /home/kde/kdemultimedia/kaboodle/engine.h,v
retrieving revision 1.14
diff -u -3 -p -u -r1.14 engine.h
--- engine.h 2002/06/06 10:56:59 1.14
+++ engine.h 2002/08/28 10:44:49
@@ -29,6 +29,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE
#include <kmediaplayer/player.h>
#include <kurl.h>
+class KPlayObject;
+
namespace Arts
{
class PlayObject;
@@ -77,6 +79,12 @@ public slots:
* skips to a time
**/
void seek(unsigned long msec);
+
+ /**
+ * attaches a playobject to the engine
+ * called by the KPlayObjectCreator
+ **/
+ void attachPlayObject(KPlayObject*);
public:
KMediaPlayer::Player::State state();
[" " (text/x-diff)]
Index: kplayobjectfactory.cc
===================================================================
RCS file: /home/kde/kdelibs/arts/kde/kplayobjectfactory.cc,v
retrieving revision 1.18
diff -u -3 -p -u -r1.18 kplayobjectfactory.cc
--- kplayobjectfactory.cc 2002/03/31 20:27:47 1.18
+++ kplayobjectfactory.cc 2002/08/28 10:45:39
@@ -44,104 +44,193 @@ KPlayObjectFactory::~KPlayObjectFactory(
{
}
-KPlayObject *KPlayObjectFactory::createPlayObject(const KURL& url, bool createBUS)
+KPlayObject *KPlayObjectFactory::createPlayObject(const KURL& url, const QString \
&mimetype, bool createBUS) {
+ if(!m_server.isNull())
+ {
+ kdDebug() << "createPlayObject: mimetype is " << mimetype << endl;
- // no need to go any further, and I hate deep indentation
- if (m_server.isNull() || url.isEmpty() )
+ if(mimetype == "application/octet-stream" && m_allowStreaming)
+ {
+ Arts::KIOInputStream instream;
+ instream.openURL(url.url().latin1());
+
+ m_stream = true;
+
+ // TODO: what else than hardcoding audio/x-mp3 ?
+ return new KPlayObject(m_server.createPlayObjectForStream(instream, \
string("audio/x-mp3"), createBUS), true); + }
+ else if(mimetype == "video/mpeg" && m_allowStreaming)
+ {
+ Arts::KIOInputStream instream;
+ instream.openURL(url.url().latin1());
+
+ m_stream = true;
+
+ return new KPlayObject(m_server.createPlayObjectForStream(instream, \
string("video/mpeg"), createBUS), true); + }
+ else
+ return new KPlayObject(m_server.createPlayObjectForURL(string(QFile::encodeName(url.path())), \
string(mimetype.latin1()), createBUS), false); + }
+ else
return new KPlayObject();
+}
+
+QStringList KPlayObjectFactory::mimeTypes(void)
+{
+ Arts::TraderQuery query;
+ vector<Arts::TraderOffer> *offers = query.query();
+ QStringList results;
+ for(vector<Arts::TraderOffer>::iterator offer = offers->begin();
+ offer != offers->end(); ++offer)
+ {
+ vector<string> *mimetypes = (*offer).getProperty("MimeType");
+
+ for(vector<string>::iterator mimetype = mimetypes->begin();
+ mimetype != mimetypes->end(); ++mimetype)
+ {
+ QString name = QString::fromLocal8Bit((*mimetype).c_str()).stripWhiteSpace();
+ if(KMimeType::mimeType(name))
+ results.append(name);
+ }
+
+ delete mimetypes;
+ }
+ delete offers;
+
+ // clean out duplicates
+ results.sort();
+ for(QStringList::iterator result = results.begin(); result != results.end(); )
+ {
+ QStringList::iterator previous = result;
+ ++result;
+ if(result != results.end() && *result == *previous)
+ {
+ results.remove(result);
+ result = previous;
+ }
+ }
+
+ return results;
+}
+
+/*
+ * Implementation of KPlayObjectCreator
+ *
+ * the functionality is duplicated from KPlayObjectFactory, but it seems
+ * impossible to extend the existing class while staying binary compatible
+ * (missing d* for example)
+ */
+
+struct KPlayObjectCreator::PrivateData {
+ Arts::SoundServerV2 server;
+ Arts::KIOInputStream instream;
+ bool createBUS;
+};
+
+KPlayObjectCreator::KPlayObjectCreator(Arts::SoundServerV2 server)
+{
+ d = new PrivateData;
+ d->server = server;
+}
+
+KPlayObjectCreator::~KPlayObjectCreator()
+{
+ delete d;
+}
+
+bool KPlayObjectCreator::create(const KURL& url, bool createBUS)
+{
+ // no need to go any further, and I hate deep indentation
+ if (d->server.isNull() || url.isEmpty() )
+ return false;
+
// check if streaming is allowed or the URL is a local file
- if (m_allowStreaming && !url.isLocalFile())
+ if (!url.isLocalFile())
{
+ d->createBUS = createBUS;
+
// This is the RightWay(tm) according to stw
Arts::KIOInputStream_impl* instream_impl = new Arts::KIOInputStream_impl();
- Arts::KIOInputStream instream = Arts::KIOInputStream::_from_base(instream_impl);
+ d->instream = Arts::KIOInputStream::_from_base(instream_impl);
// signal will be called once the ioslave knows the mime-type of the stream
QObject::connect(instream_impl, SIGNAL(mimeTypeFound(const QString &)),
this, SLOT(slotMimeType(const QString &)));
// GO!
- instream.openURL(url.url().latin1());
- instream.streamStart();
+ d->instream.openURL(url.url().latin1());
+ d->instream.streamStart();
- m_eventLoopEntered = true;
- // FIXME: need to handle timeouts?
- // this is UGLY, but I cannot do anything else without changing the interface
- // the application blocks here, and restarts once slotMimeType() is called.
- kapp->enter_loop();
-
- // wb :D
- // some error occoured
- if (m_mimeType == "application/x-zerosize")
- return new KPlayObject();
-
- // ok, now we know the mimetype of the stream
- m_stream = true;
- return new KPlayObject(m_server.createPlayObjectForStream(instream,
- string(m_mimeType.latin1()),
- createBUS), true);
+ return true;
}
kdDebug() << "stream is local file: " << url.url() << endl;
// usual stuff if we have a local file
KMimeType::Ptr mimetype = KMimeType::findByURL(url);
- return new KPlayObject(m_server.createPlayObjectForURL(string(QFile::encodeName(url.path())), \
- string(mimetype->name().latin1()),
- createBUS),
- false);
+ emit playObjectCreated (
+ new KPlayObject(d->server.createPlayObjectForURL(string(QFile::encodeName(url.path())), \
+ string(mimetype->name().latin1()),
+ createBUS), false)
+ );
+ return true;
}
-void KPlayObjectFactory::slotMimeType(const QString& mimetype)
+void KPlayObjectCreator::slotMimeType(const QString& mimetype)
{
kdDebug() << "slotMimeType called: " << mimetype << endl;
- if ( mimetype == "application/octet-stream" )
- m_mimeType = "audio/x-mp3";
- else
- m_mimeType = mimetype;
+ QString mimetype_copy = mimetype;
- if (m_eventLoopEntered) {
- m_eventLoopEntered = false;
- kapp->exit_loop();
- }
+ if ( mimetype_copy == "application/octet-stream" )
+ mimetype_copy = QString("audio/x-mp3");
+
+ if (mimetype_copy == "application/x-zerosize")
+ emit playObjectCreated(new KPlayObject());
+
+ emit playObjectCreated (
+ new KPlayObject(d->server.createPlayObjectForStream(
+ d->instream, string(mimetype_copy.latin1()), d->createBUS), true)
+ );
}
-KPlayObject *KPlayObjectFactory::createPlayObject(const KURL& url, const QString \
&mimetype, bool createBUS) +bool KPlayObjectCreator::create(const KURL& url, const \
QString &mimetype, bool createBUS) {
- if(!m_server.isNull())
+ if (d->server.isNull() || url.isEmpty())
+ return false;
+
+ kdDebug() << "create: mimetype is " << mimetype << endl;
+
+ if (url.isLocalFile())
{
- kdDebug() << "createPlayObject: mimetype is " << mimetype << endl;
-
- if(mimetype == "application/octet-stream" && m_allowStreaming)
- {
- Arts::KIOInputStream instream;
- instream.openURL(url.url().latin1());
-
- m_stream = true;
+ kdDebug() << "url " << url.url() << " is a local file\n";
- // TODO: what else than hardcoding audio/x-mp3 ?
- return new KPlayObject(m_server.createPlayObjectForStream(instream, \
string("audio/x-mp3"), createBUS), true);
- }
- else if(mimetype == "video/mpeg" && m_allowStreaming)
- {
- Arts::KIOInputStream instream;
- instream.openURL(url.url().latin1());
-
- m_stream = true;
-
- return new KPlayObject(m_server.createPlayObjectForStream(instream, \
string("video/mpeg"), createBUS), true);
- }
- else
- return new KPlayObject(m_server.createPlayObjectForURL(string(QFile::encodeName(url.path())), \
string(mimetype.latin1()), createBUS), false); + emit playObjectCreated(
+ new KPlayObject(d->server.createPlayObjectForURL(
+ string(QFile::encodeName(url.path())),
+ string(mimetype.latin1()), createBUS),
+ false)
+ );
}
else
- return new KPlayObject();
+ {
+ kdDebug() << "url " << url.url() << " is a stream\n";
+
+ Arts::KIOInputStream instream;
+ instream.openURL(url.url().latin1());
+ emit playObjectCreated(
+ new KPlayObject(d->server.createPlayObjectForStream(
+ instream,
+ string(mimetype.latin1()),
+ createBUS), true)
+ );
+ }
+ return true;
}
-QStringList KPlayObjectFactory::mimeTypes(void)
+QStringList KPlayObjectCreator::mimeTypes(void)
{
Arts::TraderQuery query;
vector<Arts::TraderOffer> *offers = query.query();
@@ -179,3 +268,21 @@ QStringList KPlayObjectFactory::mimeType
return results;
}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: kplayobjectfactory.h
===================================================================
RCS file: /home/kde/kdelibs/arts/kde/kplayobjectfactory.h,v
retrieving revision 1.11
diff -u -3 -p -u -r1.11 kplayobjectfactory.h
--- kplayobjectfactory.h 2002/03/31 20:27:47 1.11
+++ kplayobjectfactory.h 2002/08/28 10:45:39
@@ -27,9 +27,8 @@
#include "soundserver.h"
#include "kplayobject.h"
-class KPlayObjectFactory : public QObject
+class KPlayObjectFactory
{
-Q_OBJECT
public:
KPlayObjectFactory(Arts::SoundServerV2 server);
~KPlayObjectFactory();
@@ -47,15 +46,41 @@ public:
*/
static QStringList mimeTypes(void);
-private slots:
- void slotMimeType(const QString &mimetype);
-
private:
Arts::SoundServerV2 m_server;
bool m_allowStreaming;
bool m_stream;
- bool m_eventLoopEntered;
- QString m_mimeType;
+};
+
+
+
+class KPlayObjectCreator : public QObject
+{
+Q_OBJECT
+public:
+ KPlayObjectCreator(Arts::SoundServerV2 server);
+ ~KPlayObjectCreator();
+
+ bool create(const KURL& url, bool createBUS);
+ bool create(const KURL& url, const QString &mimetype, bool createBUS);
+
+ /**
+ * Return the mimetypes that are playable
+ */
+ static QStringList mimeTypes(void);
+
+signals:
+ void playObjectCreated(KPlayObject* playObject);
+
+private slots:
+ void slotMimeType(const QString &mimetype);
+
+private:
+ struct PrivateData;
+ PrivateData* d;
};
#endif
+
+
+
[Attachment #7 (application/pgp-signature)]
_______________________________________________
kde-multimedia mailing list
kde-multimedia@mail.kde.org
http://mail.kde.org/mailman/listinfo/kde-multimedia
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic