Index: abstractmediaproducer.h =================================================================== --- abstractmediaproducer.h (revisione 570567) +++ abstractmediaproducer.h (copia locale) @@ -67,10 +67,10 @@ Q_INVOKABLE qint64 currentTime() const; Q_INVOKABLE qint32 tickInterval() const; Q_INVOKABLE void setTickInterval( qint32 newTickInterval ); - Q_INVOKABLE void play(); - Q_INVOKABLE void pause(); + virtual Q_INVOKABLE void play(); + virtual Q_INVOKABLE void pause(); virtual Q_INVOKABLE void stop(); - Q_INVOKABLE void seek( qint64 time ); + virtual Q_INVOKABLE void seek( qint64 time ); Q_INVOKABLE qint32 aboutToFinishTime() const; Q_INVOKABLE void setAboutToFinishTime( qint32 newAboutToFinishTime ); @@ -119,8 +119,9 @@ bool m_aboutToFinishNotEmitted; - protected Q_SLOTS: - void emitTick(); + protected Q_SLOTS: + void emitTick(); + Result endTrack(); //this will be called by the nmm, when the endTrack event occurs private: Phonon::State m_state; @@ -132,14 +133,13 @@ QHash m_selectedSubtitleStream; void setupGraph(); //this will cause the EventListeners to be registered and the composite node to be set. - TEDObject0 m_endTrackListener; TEDObject1 m_trackDurationListener; TEDObject1 m_timeProgressListener; - Result endTrack(); //this will be called by the nmm, when the endTrack event occurs Result trackDuration(Interval& i); Result setTimeProgress(Time& current); Backend* m_backend; + int m_endTrackReceived; }; }} //namespace Phonon::nmm Index: audiopath.h =================================================================== --- audiopath.h (revisione 570567) +++ audiopath.h (copia locale) @@ -55,7 +55,10 @@ void setBranchId(int id); int getBranchId(); bool insertInto(NMM::GraphHandler* graph); - + + Q_SIGNALS: + void endTrack(); + private: bool internal_insertInto(NMM::GraphHandler* graph); QList m_effects; Index: audiooutput.h =================================================================== --- audiooutput.h (revisione 570567) +++ audiooutput.h (copia locale) @@ -26,7 +26,7 @@ #define Phonon_NMM_AUDIOOUTPUT_H #include "abstractaudiooutput.h" - +#include namespace NMM { class INode; @@ -60,6 +60,7 @@ Q_SIGNALS: void volumeChanged( float newVolume ); + void endTrack(); private: float m_volume; @@ -68,6 +69,8 @@ Backend* m_backend; NMM::INode* m_sink; NMM::IAudioDevice* m_audioDevice; + NMM::TEDObject0 m_endTrackListener; + NMM::Result endTrackCb(); }; }} //namespace Phonon::nmm Index: abstractmediaproducer.cpp =================================================================== --- abstractmediaproducer.cpp (revisione 570567) +++ abstractmediaproducer.cpp (copia locale) @@ -49,10 +49,10 @@ , m_state( Phonon::LoadingState ) , m_tickInterval( 0 ) , m_lastSeek(0) - , m_endTrackListener(this, &AbstractMediaProducer::endTrack) , m_trackDurationListener(this, &AbstractMediaProducer::trackDuration) , m_timeProgressListener(this, &AbstractMediaProducer::setTimeProgress) , m_backend( backend ) + , m_endTrackReceived(0) { kDebug() << k_funcinfo << endl; @@ -70,6 +70,8 @@ if (m_graphHandler!=0) delete m_graphHandler; m_graphHandler=0; + m_cnode=0; + m_eventHandlerRegistered=false; //if (m_config!=0) //delete m_config; @@ -96,7 +98,6 @@ if (m_cnode == 0) m_cnode = m_graphHandler->getCompositeNode(); - m_cnode->registerEventListener(ITrack::endTrack_event, &m_endTrackListener); m_cnode->registerEventListener(ITrackDuration::trackDuration_event, &m_trackDurationListener); m_cnode->registerEventListener(ITimeProgressListener::setTimeProgress_event, &m_timeProgressListener); m_eventHandlerRegistered = true; @@ -187,6 +188,7 @@ foreach( AudioPath* ap, m_audioPathList ) { ret &= ap->insertInto(m_graphHandler); + connect(ap, SIGNAL(endTrack()), SLOT(endTrack())); } return ret; } @@ -199,13 +201,13 @@ State AbstractMediaProducer::state() const { - kDebug() << k_funcinfo << endl; + //kDebug() << k_funcinfo << endl; return m_state; } bool AbstractMediaProducer::hasVideo() const { - kDebug() << k_funcinfo << endl; + //kDebug() << k_funcinfo << endl; try { return m_graphHandler->hasVideo(); @@ -255,17 +257,14 @@ m_tickInterval = newTickInterval; m_graphHandler->setTimeReportInterval(m_tickInterval); - //if( m_tickInterval <= 0 ) - // m_tickTimer->setInterval( 50 ); - //else - // TODO actually set it } void AbstractMediaProducer::play() { kDebug() << k_funcinfo << endl; m_currentTime=-1; - + m_endTrackReceived=0; + if (state() == Phonon::PausedState) { IMultiAudioVideoSynchronizer* synchronizer = m_avSync.getCheckedInterface(); @@ -360,22 +359,6 @@ m_lastSeek=time; m_cnode->flush(); -#if 0 - switch( state() ) - { - case Phonon::PausedState: - case Phonon::BufferingState: - //m_startTime = m_pauseTime; - break; - case Phonon::PlayingState: - //m_startTime = QTime::currentTime(); - break; - case Phonon::StoppedState: - case Phonon::ErrorState: - case Phonon::LoadingState: - return; // cannot seek - } -#endif } } @@ -490,9 +473,13 @@ Result AbstractMediaProducer::endTrack() { //emit finished();//don't do this. everything will be stopped immediately - kDebug() << "got end track event" << endl; - this->seek(0); - this->stop(); + kDebug() << "****************** got end track event" << endl; + if (!m_endTrackReceived) + { + this->seek(0); + this->stop(); + } + m_endTrackReceived++; return SUCCESS; } Index: audiopath.cpp =================================================================== --- audiopath.cpp (revisione 570567) +++ audiopath.cpp (copia locale) @@ -59,6 +59,7 @@ bool AudioPath::removeOutput( QObject* audioOutput ) { + kDebug()<( audioOutput ); Q_ASSERT( ao ); @@ -105,13 +106,14 @@ { m_graphHandler=graph; if (m_outputs.empty()) - return true; //addition scheduled for later + return true; //addition scheduled for later, we don't have outputs now return internal_insertInto(graph); } bool AudioPath::internal_insertInto(NMM::GraphHandler* graph) { AudioOutput* firstAudioOutput=static_cast(*m_outputs.begin()); + connect(firstAudioOutput, SIGNAL(endTrack()), SIGNAL(endTrack())); try { int channel = 0; //default channel Index: bytestream.cpp =================================================================== --- bytestream.cpp (revisione 570567) +++ bytestream.cpp (copia locale) @@ -112,6 +112,8 @@ try { #warning What happens if tb doesn't carry enough data? is this the lockup we're seeing with Ogg Vorbis? +#warning Make stage1 asyncronous: wait(an event) untill stage1 is reached before enabling playback. +#warning Send data even if stage1 is not reached. m_iByteStream=m_graphHandler->stage1_bs(*m_backend->nmmApplication(), tb); m_graph_init_done=true; //check if paths had already been added @@ -125,7 +127,10 @@ } } else + { m_iByteStream->sendBuffer2(tb); + kDebug()<<"m_iByteStream->getSize()=="<getSize()<getSize()=="<getSize()<getSize() == 0 ) - { - emit finished(); - stop(); - } } - else if( m_iByteStream->getSize() <= m_iByteStream->getMaxSize() /2 ) // don't let use it too much +#endif + if( m_iByteStream->getSize() <= 2 ) // go in buffering state if buffer is too low { - kDebug()<<" emit needData()"<getSize() <= 2 ) // go in buffering state if buffer is too low + else if( m_iByteStream->getSize() <= (m_iByteStream->getMaxSize() + 1) /2 ) // don't let use it too much { - kDebug()<<" Buffering" < #include +#include #include #include @@ -39,6 +40,7 @@ , m_backend( backend ) , m_sink( 0 ) , m_audioDevice( 0 ) + , m_endTrackListener(this, &AudioOutput::endTrackCb) { kDebug()<< k_funcinfo << endl; setOutputDevice(10001); //ALSAPlaybackNode @@ -116,9 +118,19 @@ NMM::INode* AudioOutput::sinkNode( ) { - return m_sink; + if (!m_sink) setOutputDevice(m_device); + NMM::INode* ret=m_sink; + if (ret) + ret->getParentObject()->registerEventListener(NMM::ITrack::endTrack_event, &m_endTrackListener); + m_sink=0; + return ret; } +NMM::Result AudioOutput::endTrackCb() +{ + emit endTrack(); +} + }} //namespace Phonon::nmm #include "audiooutput.moc" Index: TODO =================================================================== --- TODO (revisione 570567) +++ TODO (copia locale) @@ -1,15 +1,21 @@ -----Phonon---- -ByteStream is BROKEN!!!! -^^^^^^^^^^^^^^^^^^^^^^^^ - Fix it ------------------------- +AudioOutput: + Recreate the sink node or fix GH: GH deletes it. + Stop: - ByteStream: there already is a flush method in ByteStreamNode: call it. - ByteStream: reset the TransferJob. + #ByteStream: there already is a flush method in ByteStreamNode: call it. [done] + #ByteStream: reset the TransferJob. [done] + ByteStream: find out how to ask NMM when it is finished playing: stop and end track does not work now! + +EndTrack: + Causes problems... investigate. + ByteStream: find out how to ask NMM when it is finished playing: stop and end track does not work now! + +Buffering: + Make buffering dinamic. Put markers in code where it will need to chage. Signals: - Phonon: use NMM signals instead of QT timers [done] - We must enable only one node as a time event producer [done] + #Phonon: use NMM signals instead of QT timers [done] + #We must enable only one node as a time event producer [done] Do it for video VideoPath: @@ -18,8 +24,8 @@ #TickInterval: # Set it the sink node. [done] -Seeking: - Check if it really works. [done: fixed] +#Seeking: +# Check if it really works. [done: fixed] AudioSelect: Phonon: allow the user to chose the audio output plugin. @@ -28,17 +34,15 @@ Phonon: add a software volume control node to each audio path/flow graph. Progess info: - ByteStream: make it work + #ByteStream: make it work [done] -Missing Slots: - Add them :-) +#Missing Slots: [done] +# Add them :-) [done] Gui: Make it work again. VideoWidget: implement it -EndTrack: - Causes problems... investigate. ----NMM---- Bug(?): Index: backend.cpp =================================================================== --- backend.cpp (revisione 570567) +++ backend.cpp (copia locale) @@ -365,7 +365,7 @@ return m_app->getRegistry(); } -NMM::INode* Backend::requestNode( NMM::NodeDescription nd_descr ) +NMM::INode* Backend::requestNode( NMM::NodeDescription nd_descr) { kDebug()<< k_funcinfo << endl; NMM::INode* inode=0;