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

List:       kde-commits
Subject:    KDE/kdemultimedia/phonon-xine
From:       Matthias Kretz <kretz () kde ! org>
Date:       2007-06-29 20:27:41
Message-ID: 1183148861.775682.25478.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 681668 by mkretz:

- fix states told to the frontend when play,stop,setUrl,play come in very fast
- clean up the racy hacks that tried to do that in XineStream
- handle Xine::ReferenceEvent by simply overwriting the mrl and opening that

 M  +23 -6     mediaobject.cpp  
 M  +1 -0      mediaobject.h  
 M  +31 -24    xinestream.cpp  
 M  +1 -3      xinestream.h  


--- trunk/KDE/kdemultimedia/phonon-xine/mediaobject.cpp #681667:681668
@@ -39,6 +39,10 @@
 
 #include <cmath>
 
+static const char *const green  = "\033[1;40;32m";
+static const char *const blue   = "\033[1;40;34m";
+static const char *const normal = "\033[0m";
+
 namespace Phonon
 {
 namespace Xine
@@ -51,7 +55,8 @@
     m_currentTitle(1),
     m_transitionTime(0),
     m_autoplayTitles(true),
-    m_fakingBuffering(false)
+    m_fakingBuffering(false),
+    m_shouldFakeBufferingOnPlay(true)
 {
     m_stream.moveToThread(&m_stream);
     m_stream.start();
@@ -290,10 +295,12 @@
 
 void MediaObject::play()
 {
-    if (m_state == Phonon::StoppedState || m_state == Phonon::LoadingState || \
m_state == Phonon::PausedState) { +    kDebug(610) << green << "PLAY" << normal << \
endl; +    m_stream.play();
+    if (m_shouldFakeBufferingOnPlay || m_state == Phonon::StoppedState || m_state == \
Phonon::LoadingState || m_state == Phonon::PausedState) { +        \
m_shouldFakeBufferingOnPlay = false;  startToFakeBuffering();
     }
-    m_stream.play();
 }
 
 void MediaObject::pause()
@@ -326,17 +333,19 @@
 
 void MediaObject::startToFakeBuffering()
 {
+    kDebug(610) << blue << "start faking" << normal << endl;
+    m_fakingBuffering = true;
     if (m_state == Phonon::BufferingState) {
         return;
+    } else if (m_state == Phonon::PlayingState) {
+        // next time we reach StoppedState from LoadingState go right into \
BufferingState +        return;
     }
 
-    // this method is for "fake" state changes the following state changes are not \
                "fakable":
-    Q_ASSERT(m_state != Phonon::PlayingState);
     kDebug(610) << "fake state change: reached BufferingState after " << m_state << \
endl;  
     Phonon::State oldstate = m_state;
     m_state = Phonon::BufferingState;
-    m_fakingBuffering = true;
 
     emit stateChanged(Phonon::BufferingState, oldstate);
 }
@@ -347,6 +356,7 @@
         if (m_fakingBuffering) {
             Q_ASSERT(m_state == BufferingState);
             m_fakingBuffering = false;
+            kDebug(610) << blue << "end faking" << normal << endl;
         }
         // BufferingState -> BufferingState, nothing to do
         return;
@@ -355,12 +365,15 @@
         Q_ASSERT(m_state == BufferingState);
         if (newstate == PlayingState || newstate == ErrorState) {
             m_fakingBuffering = false;
+            kDebug(610) << blue << "end faking" << normal << endl;
             oldstate = m_state;
         } else {
             // we're faking BufferingState and stay there until we either reach \
BufferingState,  // PlayingState or ErrorState
             return;
         }
+    } else if (oldstate == LoadingState && newstate == StoppedState && \
m_fakingBuffering) { +        newstate = BufferingState;
     }
     m_state = newstate;
 
@@ -446,6 +459,7 @@
         if (source.url().scheme() == QLatin1String("kbytestream")) {
             m_mediaSource = MediaSource();
             kError(610) << "do not ever use kbytestream:/ URLs with MediaObject!" << \
endl; +            m_shouldFakeBufferingOnPlay = false;
             stream().setMrl(QByteArray());
             stream().setError(Phonon::NormalError, i18n("Cannot open media data at \
'<i>%1</i>'", source.url().toString(QUrl::RemovePassword)));  return;
@@ -455,6 +469,7 @@
             m_stream.gaplessSwitchTo(source.url());
             break;
         case HardSwitch:
+            m_shouldFakeBufferingOnPlay = true;
             m_stream.setUrl(source.url());
             break;
         }
@@ -491,6 +506,7 @@
                 m_stream.gaplessSwitchTo(mrl);
                 break;
             case HardSwitch:
+                m_shouldFakeBufferingOnPlay = true;
                 m_stream.setMrl(mrl);
                 break;
             }
@@ -506,6 +522,7 @@
                 m_stream.gaplessSwitchTo(m_bytestream->mrl());
                 break;
             case HardSwitch:
+                m_shouldFakeBufferingOnPlay = true;
                 m_stream.setMrl(m_bytestream->mrl());
                 break;
             }
--- trunk/KDE/kdemultimedia/phonon-xine/mediaobject.h #681667:681668
@@ -169,6 +169,7 @@
             qint32 m_transitionTime;
             bool m_autoplayTitles : 1;
             bool m_fakingBuffering : 1;
+            bool m_shouldFakeBufferingOnPlay : 1;
 	};
 }} //namespace Phonon::Xine
 
--- trunk/KDE/kdemultimedia/phonon-xine/xinestream.cpp #681667:681668
@@ -184,8 +184,7 @@
     m_prefinishMarkReachedNotEmitted(true),
     m_ticking(false),
     m_closing(false),
-    m_eventLoopReady(false),
-    m_playCalled(false)
+    m_eventLoopReady(false)
 {
 }
 
@@ -200,7 +199,7 @@
 }
 
 // xine thread
-bool XineStream::xineOpen()
+bool XineStream::xineOpen(Phonon::State newstate)
 {
     Q_ASSERT(QThread::currentThread() == this);
     Q_ASSERT(m_stream);
@@ -255,11 +254,7 @@
     emit length(m_totalTime);
     updateMetaData();
     // if there's a PlayCommand in the event queue the state should not go to \
                StoppedState
-    if (m_playCalled > 0) {
-        changeState(Phonon::BufferingState);
-    } else {
-        changeState(Phonon::StoppedState);
-    }
+    changeState(newstate);
     return true;
 }
 
@@ -347,7 +342,7 @@
     if (m_stream && !m_mrl.isEmpty()) {
         if (xine_get_status(m_stream) == XINE_STATUS_IDLE) {
             kDebug(610) << "calling xineOpen from " << k_funcinfo << endl;
-            if (!xineOpen()) {
+            if (!xineOpen(Phonon::StoppedState)) {
                 return;
             }
         }
@@ -583,7 +578,8 @@
         if (m_prefinishMarkTimer) {
             m_prefinishMarkTimer->stop();
         }
-    } else if (newstate == Phonon::ErrorState) {
+    }
+    if (newstate == Phonon::ErrorState) {
         kDebug(610) << "reached error state from: " << kBacktrace() << endl;
         if (m_event_queue) {
             xine_event_dispose_queue(m_event_queue);
@@ -651,6 +647,8 @@
 const char* nameForEvent(int e)
 {
     switch (e) {
+        case Xine::ReferenceEvent:
+            return "Xine::ReferenceEvent";
         case Xine::UiChannelsChangedEvent:
             return "Xine::UiChannelsChangedEvent";
         case Xine::MediaFinishedEvent:
@@ -729,6 +727,22 @@
         }
     }
     switch (ev->type()) {
+    case Xine::ReferenceEvent:
+        ev->accept();
+        {
+            XineReferenceEvent *e = static_cast<XineReferenceEvent *>(ev);
+            m_mrl = e->mrl;
+            if (xine_get_status(m_stream) != XINE_STATUS_IDLE) {
+                m_mutex.lock();
+                xine_close(m_stream);
+                m_streamInfoReady = false;
+                m_prefinishMarkReachedNotEmitted = true;
+                m_mutex.unlock();
+            }
+            xineOpen(Phonon::BufferingState);
+            internalPlay();
+        }
+        return true;
     case Xine::UiChannelsChangedEvent:
         ev->accept();
         // check chapter, title, angle and substreams
@@ -896,8 +910,7 @@
                 }
                 m_prefinishMarkReachedNotEmitted = true;
                 getStreamInfo();
-                xine_get_pos_length(m_stream, 0, &m_currentTime, &m_totalTime);
-                emit length(m_totalTime);
+                updateTime();
                 updateMetaData();
             }
             return true;
@@ -971,7 +984,7 @@
                     m_waitingForClose.wakeAll();
                 } else {
                     kDebug(610) << "calling xineOpen from MrlChanged" << endl;
-                    xineOpen();
+                    xineOpen(Phonon::StoppedState);
                     switch (e->stateForNewMrl) {
                     case StoppedState:
                         break;
@@ -1134,9 +1147,6 @@
             if (m_state == Phonon::ErrorState || m_state == Phonon::PlayingState) {
                 return true;
             }
-            m_playMutex.lock();
-            m_playCalled = false;
-            m_playMutex.unlock();
             Q_ASSERT(!m_mrl.isEmpty());
             /*if (m_mrl.isEmpty()) {
                 kError(610) << "PlayCommand: m_mrl is empty. This should not \
happen." << endl; @@ -1165,7 +1175,7 @@
                 //X                 }
                 if (xine_get_status(m_stream) == XINE_STATUS_IDLE) {
                     kDebug(610) << "calling xineOpen from PlayCommand" << endl;
-                    if (!xineOpen()) {
+                    if (!xineOpen(Phonon::BufferingState)) {
                         return true;
                     }
                 }
@@ -1193,8 +1203,8 @@
                 }
             }
             if (xine_get_status(m_stream) == XINE_STATUS_IDLE) {
-                kDebug(610) << "calling xineOpen from PlayCommand" << endl;
-                if (!xineOpen()) {
+                kDebug(610) << "calling xineOpen from PauseCommand" << endl;
+                if (!xineOpen(Phonon::StoppedState)) {
                     return true;
                 }
             }
@@ -1366,16 +1376,13 @@
 // called from main thread
 void XineStream::setMrl(const QByteArray &mrl, StateForNewMrl sfnm)
 {
-    kDebug(610) << k_funcinfo << mrl << endl;
+    kDebug(610) << k_funcinfo << mrl << ", " << sfnm << endl;
     QCoreApplication::postEvent(this, new MrlChangedEvent(mrl, sfnm));
 }
 
 // called from main thread
 void XineStream::play()
 {
-    m_playMutex.lock();
-    m_playCalled = true;
-    m_playMutex.unlock();
     QCoreApplication::postEvent(this, new \
QEvent(static_cast<QEvent::Type>(PlayCommand)));  }
 
@@ -1413,7 +1420,7 @@
 
     if (xine_get_status(m_stream) == XINE_STATUS_IDLE) {
         kDebug(610) << "calling xineOpen from " << k_funcinfo << endl;
-        if (!xineOpen()) {
+        if (!xineOpen(Phonon::StoppedState)) {
             return false;
         }
     }
--- trunk/KDE/kdemultimedia/phonon-xine/xinestream.h #681667:681668
@@ -154,7 +154,7 @@
 
     private:
         void getStreamInfo();
-        bool xineOpen();
+        bool xineOpen(Phonon::State);
         void updateMetaData();
         void rewireOutputPorts();
         bool createStream();
@@ -177,7 +177,6 @@
         Phonon::State m_state;
 
         QMutex m_portMutex;
-        QMutex m_playMutex;
         mutable QMutex m_mutex;
         mutable QMutex m_streamInfoMutex;
         mutable QMutex m_updateTimeMutex;
@@ -216,7 +215,6 @@
         bool m_ticking : 1;
         bool m_closing : 1;
         bool m_eventLoopReady : 1;
-        bool m_playCalled : 1;
 };
 
 } // namespace Xine


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

Configure | About | News | Add a list | Sponsored by KoreLogic