[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-multimedia
Subject:    Patch for Kaiman
From:       Antonio Larrosa <larrosa () larrosa ! org>
Date:       2000-08-24 16:34:34
[Download RAW message or body]

Hi,

I've noticed that aRts crashes some times when playing "corrupted"(?)
files and this makes Kaiman crash too.

The attached patch makes Kaiman "feel" more stable, as it detects when
aRts has crashed, try to run it again and re-connect to it. Also, if
aRts is not running when starting Kaiman, it starts it instead of
asking the user to do it by himself.

To try it, just killall artsd, run Kaiman, play a file, while it's
being played killall artsd, and click on play again, then killall artsd,
and click on quit. You can try those three tests with and without the
patch to see the difference.

There are three things in this patch that I'm not sure to be the best
solutions. First, I used sometimes soundServer = Arts::Reference(....);
If the name is right and it's a reference, there's no problem with
getting it many times, but if that function returns a new copy, then
the patch is wrong because it will leak memory.

The second problem is that I cannot use -d when running aRts from Kaiman
(although it works when running aRts from a Konsole).

The third problem is that there's a race condition when starting aRts.
Anyway, I'm not very worried about this, as in the worst case of the
race condition we get the current behaviour and in the best case, we
get a much better behaviour.

Stefan, can you comment on the two first issues ?

Greetings,

Btw, Martin Vogt has made an excellent plugin for avi/divx support in
aRts (available from mpeglib.sourceforge.net ), and it works quite well
(I've already played complete movies with it :) ). As it's too late for
it to be included into kdemultimedia, I'd like to know if there's any
way that we can make it more available to users. Should we leave this
task to the distributions (I don't think so) ? Any idea ?

--
Antonio Larrosa Jimenez
KDE Core developer
antonio@larrosa.org        larrosa@kde.org
http://www.arrakis.es/~rlarrosa
KDE - The development framework of the future, today.
["kaiman.diff" (text/plain)]

--- kaiman.cpp	Thu Aug 17 20:42:36 2000
+++ kaiman.cpp.new	Thu Aug 24 16:15:43 2000
@@ -37,6 +37,10 @@
 #include <qdropsite.h>
 #include <qdragobject.h>
 
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+
 #include <X11/X.h>
 #include <X11/Xos.h>
 #include <X11/Xlib.h>
@@ -56,6 +60,12 @@
 #define STATUS_POLL_DELAY 200
 #define ARTS_POLL_DELAY 500
 
+bool artswrapper_check()
+{
+    if(system("artswrapper check") == 0)
+        return true;
+    return false;
+}                                                                                    \
  
 using namespace Arts;
 
@@ -76,22 +86,7 @@
 
     setAcceptDrops(true);
 
-    // Arts init
-    _playObjectFactory = Arts::Reference("global:Arts_PlayObjectFactory");
-
-    if(_playObjectFactory.isNull())
-    {
-        KMessageBox::error( 0, i18n("Connection to the soundserver failed - make \
                sure that artsd is really running.") );
-        exit(1);
-    }
-
-    _playObject = Arts::PlayObject::null();
-    _lastPolledState = Arts::posIdle;
-
-    // create a new stereo volume control object on the server
-    _volumeControl = \
                DynamicCast(_soundServer.createObject("Arts::StereoVolumeControl"));
-    _volumeControl.start();
-    _volumeEffectID = _soundServer.outstack().insertBottom(_volumeControl, "Volume \
Control"); +    if (!initArts()) exit(1);
 
     // load skin
     QString skinName;
@@ -145,6 +140,9 @@
     config->writeEntry( "Skin", _style->skinName() );
     config->writeEntry( "Playlist", _mediaManager->fileName().url() );
 
+    // get a reference to the server to be sure that we're still connected
+    _soundServer=Reference("global:Arts_SimpleSoundServer");
+
     // remove effect from effect chain
     if ( !_soundServer.isNull() )
         _soundServer.outstack().remove( _volumeEffectID );
@@ -153,6 +151,95 @@
     delete _mediaManager;
 }
 
+bool Kaiman::initArts()
+{
+    _playObjectFactory = Arts::Reference("global:Arts_PlayObjectFactory");
+
+    if(_playObjectFactory.isNull())
+    {
+        // aRts seems not to be running, let's try to run it
+
+        // First, let's read the configuration as in kcmarts
+
+        KConfig *config = new KConfig("kcmartsrc");
+        QCString cmdline;
+ 
+        config->setGroup("Arts");
+        bool startRealtime = config->readBoolEntry("StartRealtime",false);
+        bool networkTransparent = config->readBoolEntry("NetworkTransparent",false);
+        bool x11Comm = config->readBoolEntry("X11GlobalComm",false);
+//        bool fullDuplex = config->readBoolEntry("FullDuplex",false);
+        int responseTime = config->readNumEntry("ResponseTime",2);
+ 
+        /* put the value of x11Comm into .mcoprc */
+        KConfig *X11CommConfig = new KConfig(QDir::homeDirPath()+"/.mcoprc");
+ 
+        if(x11Comm)
+            X11CommConfig->writeEntry("GlobalComm","Arts::X11GlobalComm");
+        else
+            X11CommConfig->writeEntry("GlobalComm","Arts::TmpGlobalComm");
+ 
+        X11CommConfig->sync();
+        delete X11CommConfig;
+ 
+        cmdline = QFile::encodeName(KStandardDirs::findExe(QString::fromLatin1("kdeinit_wrapper")));
 +        cmdline += " ";
+        if(startRealtime && artswrapper_check())
+            cmdline += \
QFile::encodeName(KStandardDirs::findExe(QString::fromLatin1("artswrapper"))); +      \
else +            cmdline += \
QFile::encodeName(KStandardDirs::findExe(QString::fromLatin1("artsd"))); +
+        if(networkTransparent)
+            cmdline += " -n";
+
+         // Full duplex seems not to work
+//        if(fullDuplex)
+//            cmdline += " -d";
+ 
+        switch(responseTime)
+        {
+            // 8.7 ms 
+            case 0: cmdline += " -F 3 -S 512";
+                break;
+            // 40 ms 
+            case 1: cmdline += " -F 7 -S 1024";
+                break;
+            // 255 ms 
+            case 2: cmdline += " -F 5 -S 8192";
+                break;
+        }
+
+        int status=system(cmdline);     
+
+        if ( status!=-1 && WIFEXITED(status) )
+        {
+         // We could have a race-condition here. The correct way to do it is to
+         // make artsd fork-and-exit after starting to listen to connections
+         // (and running artsd directly instead of using kdeinit),
+         // but this is better than nothing.
+          sleep(1);
+          _soundServer=Reference("global:Arts_SimpleSoundServer");
+          _playObjectFactory = Arts::Reference("global:Arts_PlayObjectFactory");
+        }
+ 
+        if(_playObjectFactory.isNull())
+        {
+           KMessageBox::error( 0, i18n("Connection to the soundserver failed - make \
sure that artsd is really running.") ); +           return false;
+        } 
+    }
+
+    _playObject = Arts::PlayObject::null();
+    _lastPolledState = Arts::posIdle;
+
+    // create a new stereo volume control object on the server
+    _volumeControl = \
DynamicCast(_soundServer.createObject("Arts::StereoVolumeControl")); +    \
_volumeControl.start(); +    _volumeEffectID = \
_soundServer.outstack().insertBottom(_volumeControl, "Volume Control"); +
+    return true;
+}
+
 bool Kaiman::loadStyle( const QString &style, const QString &desc )
 {
     if ( _style ) delete _style;
@@ -257,11 +344,26 @@
     kdDebug() << " Kaiman::play " << file << endl;
     _playObject = _playObjectFactory.createPlayObject( file.ascii() );
 
-    if ( !_playObject.isNull() ) {
-        _playObject.play();
-        return _playObject.state()==Arts::posPlaying;
-    } else
-        return false;
+    if ( _playObject.isNull() ) {
+
+       // Let's check if the connection with arts was broken
+       _playObjectFactory = Arts::Reference("global:Arts_PlayObjectFactory");
+
+       if(!_playObjectFactory.isNull()) return false;
+
+       // It was broken, so let's try to reestablish it again
+
+       if (!initArts()) return false;
+
+       // Cool, we were able to connect.
+
+       _playObject = _playObjectFactory.createPlayObject( file.ascii() );
+
+       if ( _playObject.isNull() ) return false;
+    }
+
+    _playObject.play();
+    return _playObject.state()==Arts::posPlaying;
 }
 
 
--- kaiman.h	Thu Aug 17 20:42:36 2000
+++ kaiman.h.new	Thu Aug 24 02:13:41 2000
@@ -85,6 +85,8 @@
     void pollArts();
 
 private:
+    bool initArts();
+
     KaimanStyle *_style;
     class MediaManager *_mediaManager;
 


_______________________________________________
Kde-multimedia mailing list
Kde-multimedia@master.kde.org
http://master.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