src/3rdparty/phonon/mmf/abstractmediaplayer.cpp
changeset 22 79de32ba3296
parent 18 2f34d5167611
child 37 758a864f9613
equal deleted inserted replaced
19:fcece45ef507 22:79de32ba3296
    46 
    46 
    47 MMF::AbstractMediaPlayer::AbstractMediaPlayer
    47 MMF::AbstractMediaPlayer::AbstractMediaPlayer
    48     (MediaObject *parent, const AbstractPlayer *player)
    48     (MediaObject *parent, const AbstractPlayer *player)
    49         :   AbstractPlayer(player)
    49         :   AbstractPlayer(player)
    50         ,   m_parent(parent)
    50         ,   m_parent(parent)
    51         ,   m_playPending(false)
    51         ,   m_pending(NothingPending)
    52         ,   m_positionTimer(new QTimer(this))
    52         ,   m_positionTimer(new QTimer(this))
    53         ,   m_bufferStatusTimer(new QTimer(this))
    53         ,   m_bufferStatusTimer(new QTimer(this))
    54         ,   m_mmfMaxVolume(NullMaxVolume)
    54         ,   m_mmfMaxVolume(NullMaxVolume)
    55         ,   m_prefinishMarkSent(false)
    55         ,   m_prefinishMarkSent(false)
    56         ,   m_aboutToFinishSent(false)
    56         ,   m_aboutToFinishSent(false)
    72     case GroundState:
    72     case GroundState:
    73         setError(tr("Not ready to play"));
    73         setError(tr("Not ready to play"));
    74         break;
    74         break;
    75 
    75 
    76     case LoadingState:
    76     case LoadingState:
    77         m_playPending = true;
    77         setPending(PlayPending);
    78         break;
    78         break;
    79 
    79 
    80     case StoppedState:
    80     case StoppedState:
    81     case PausedState:
    81     case PausedState:
    82         doPlay();
    82         startPlayback();
    83         startPositionTimer();
       
    84         changeState(PlayingState);
       
    85         break;
    83         break;
    86 
    84 
    87     case PlayingState:
    85     case PlayingState:
    88     case BufferingState:
    86     case BufferingState:
    89     case ErrorState:
    87     case ErrorState:
   101 void MMF::AbstractMediaPlayer::pause()
    99 void MMF::AbstractMediaPlayer::pause()
   102 {
   100 {
   103     TRACE_CONTEXT(AbstractMediaPlayer::pause, EAudioApi);
   101     TRACE_CONTEXT(AbstractMediaPlayer::pause, EAudioApi);
   104     TRACE_ENTRY("state %d", privateState());
   102     TRACE_ENTRY("state %d", privateState());
   105 
   103 
   106     m_playPending = false;
       
   107     stopTimers();
   104     stopTimers();
   108 
   105 
   109     switch (privateState()) {
   106     switch (privateState()) {
   110     case GroundState:
   107     case GroundState:
   111     case LoadingState:
   108     case LoadingState:
       
   109     case StoppedState:
       
   110         setPending(PausePending);
       
   111         break;
       
   112 
   112     case PausedState:
   113     case PausedState:
   113     case StoppedState:
       
   114         // Do nothing
   114         // Do nothing
   115         break;
   115         break;
   116 
   116 
   117     case PlayingState:
   117     case PlayingState:
   118     case BufferingState:
   118     case BufferingState:
   133 void MMF::AbstractMediaPlayer::stop()
   133 void MMF::AbstractMediaPlayer::stop()
   134 {
   134 {
   135     TRACE_CONTEXT(AbstractMediaPlayer::stop, EAudioApi);
   135     TRACE_CONTEXT(AbstractMediaPlayer::stop, EAudioApi);
   136     TRACE_ENTRY("state %d", privateState());
   136     TRACE_ENTRY("state %d", privateState());
   137 
   137 
   138     m_playPending = false;
   138     setPending(NothingPending);
   139     stopTimers();
   139     stopTimers();
   140 
   140 
   141     switch (privateState()) {
   141     switch (privateState()) {
   142     case GroundState:
   142     case GroundState:
   143     case LoadingState:
   143     case LoadingState:
   363 {
   363 {
   364     m_mmfMaxVolume = mmfMaxVolume;
   364     m_mmfMaxVolume = mmfMaxVolume;
   365     doVolumeChanged();
   365     doVolumeChanged();
   366 }
   366 }
   367 
   367 
       
   368 void MMF::AbstractMediaPlayer::loadingComplete(int error)
       
   369 {
       
   370     Q_ASSERT(Phonon::LoadingState == state());
       
   371 
       
   372     if (KErrNone == error) {
       
   373         updateMetaData();
       
   374         changeState(StoppedState);
       
   375     } else {
       
   376         setError(tr("Loading clip failed"), error);
       
   377     }
       
   378 }
       
   379 
   368 void MMF::AbstractMediaPlayer::playbackComplete(int error)
   380 void MMF::AbstractMediaPlayer::playbackComplete(int error)
   369 {
   381 {
   370     stopTimers();
   382     stopTimers();
   371 
   383 
       
   384     if (KErrNone == error && !m_aboutToFinishSent) {
       
   385         const qint64 total = totalTime();
       
   386         emit MMF::AbstractPlayer::tick(total);
       
   387         m_aboutToFinishSent = true;
       
   388         emit aboutToFinish();
       
   389     }
       
   390 
   372     if (KErrNone == error) {
   391     if (KErrNone == error) {
   373         changeState(StoppedState);
   392         changeState(PausedState);
   374 
   393 
   375         // MediaObject::switchToNextSource deletes the current player, so we
   394         // MediaObject::switchToNextSource deletes the current player, so we
   376         // call it via delayed slot invokation to ensure that this object does
   395         // call it via delayed slot invokation to ensure that this object does
   377         // not get deleted during execution of a member function.
   396         // not get deleted during execution of a member function.
   378         QMetaObject::invokeMethod(m_parent, "switchToNextSource", Qt::QueuedConnection);
   397         QMetaObject::invokeMethod(m_parent, "switchToNextSource", Qt::QueuedConnection);
   379     }
   398     }
   380     else {
   399     else {
   381         setError(tr("Playback complete"), error);
   400         setError(tr("Playback complete"), error);
       
   401         emit finished();
   382     }
   402     }
   383 }
   403 }
   384 
   404 
   385 qint64 MMF::AbstractMediaPlayer::toMilliSeconds(const TTimeIntervalMicroSeconds &in)
   405 qint64 MMF::AbstractMediaPlayer::toMilliSeconds(const TTimeIntervalMicroSeconds &in)
   386 {
   406 {
   391 // Slots
   411 // Slots
   392 //-----------------------------------------------------------------------------
   412 //-----------------------------------------------------------------------------
   393 
   413 
   394 void MMF::AbstractMediaPlayer::positionTick()
   414 void MMF::AbstractMediaPlayer::positionTick()
   395 {
   415 {
   396     emitMarksIfReached();
       
   397 
       
   398     const qint64 current = currentTime();
   416     const qint64 current = currentTime();
       
   417     emitMarksIfReached(current);
   399     emit MMF::AbstractPlayer::tick(current);
   418     emit MMF::AbstractPlayer::tick(current);
   400 }
   419 }
   401 
   420 
   402 void MMF::AbstractMediaPlayer::emitMarksIfReached()
   421 void MMF::AbstractMediaPlayer::emitMarksIfReached(qint64 current)
   403 {
   422 {
   404     const qint64 current = currentTime();
       
   405     const qint64 total = totalTime();
   423     const qint64 total = totalTime();
   406     const qint64 remaining = total - current;
   424     const qint64 remaining = total - current;
   407 
   425 
   408     if (prefinishMark() && !m_prefinishMarkSent) {
   426     if (prefinishMark() && !m_prefinishMarkSent) {
   409         if (remaining < (prefinishMark() + tickInterval()/2)) {
   427         if (remaining < (prefinishMark() + tickInterval()/2)) {
   433     if (m_aboutToFinishSent)
   451     if (m_aboutToFinishSent)
   434         if (remaining >= tickInterval())
   452         if (remaining >= tickInterval())
   435             m_aboutToFinishSent = false;
   453             m_aboutToFinishSent = false;
   436 }
   454 }
   437 
   455 
       
   456 void MMF::AbstractMediaPlayer::setPending(Pending pending)
       
   457 {
       
   458     const Phonon::State oldState = state();
       
   459     m_pending = pending;
       
   460     const Phonon::State newState = state();
       
   461     if (newState != oldState)
       
   462         emit stateChanged(newState, oldState);
       
   463 }
       
   464 
       
   465 void MMF::AbstractMediaPlayer::startPlayback()
       
   466 {
       
   467     doPlay();
       
   468     startPositionTimer();
       
   469     changeState(PlayingState);
       
   470 }
       
   471 
   438 void MMF::AbstractMediaPlayer::bufferStatusTick()
   472 void MMF::AbstractMediaPlayer::bufferStatusTick()
   439 {
   473 {
   440     emit MMF::AbstractPlayer::bufferStatus(bufferStatus());
   474     emit MMF::AbstractPlayer::bufferStatus(bufferStatus());
       
   475 }
       
   476 
       
   477 Phonon::State MMF::AbstractMediaPlayer::phononState(PrivateState state) const
       
   478 {
       
   479     Phonon::State result = AbstractPlayer::phononState(state);
       
   480 
       
   481     if (PausePending == m_pending) {
       
   482         Q_ASSERT(Phonon::StoppedState == result || Phonon::LoadingState == result);
       
   483         result = Phonon::PausedState;
       
   484     }
       
   485 
       
   486     return result;
   441 }
   487 }
   442 
   488 
   443 void MMF::AbstractMediaPlayer::changeState(PrivateState newState)
   489 void MMF::AbstractMediaPlayer::changeState(PrivateState newState)
   444 {
   490 {
   445     TRACE_CONTEXT(AbstractMediaPlayer::changeState, EAudioInternal);
   491     TRACE_CONTEXT(AbstractMediaPlayer::changeState, EAudioInternal);
   446 
   492 
   447     const Phonon::State oldPhononState = phononState(privateState());
   493     const Phonon::State oldPhononState = phononState(privateState());
   448     const Phonon::State newPhononState = phononState(newState);
   494     const Phonon::State newPhononState = phononState(newState);
   449 
   495 
   450     // TODO: add some invariants to check that the transition is valid
       
   451     AbstractPlayer::changeState(newState);
       
   452 
       
   453     if (LoadingState == oldPhononState && StoppedState == newPhononState) {
   496     if (LoadingState == oldPhononState && StoppedState == newPhononState) {
   454         // Ensure initial volume is set on MMF API before starting playback
   497         switch (m_pending) {
   455         doVolumeChanged();
   498         case NothingPending:
   456 
   499             AbstractPlayer::changeState(newState);
   457         // Check whether play() was called while clip was being loaded.  If so,
   500             break;
   458         // playback should be started now
   501 
   459         if (m_playPending) {
   502         case PlayPending:
   460             TRACE_0("play was called while loading; starting playback now");
   503             changeState(PlayingState); // necessary in order to apply initial volume
   461             m_playPending = false;
   504             doVolumeChanged();
   462             play();
   505             startPlayback();
   463         }
   506             break;
       
   507 
       
   508         case PausePending:
       
   509             AbstractPlayer::changeState(PausedState);
       
   510             break;
       
   511         }
       
   512 
       
   513         setPending(NothingPending);
       
   514     } else {
       
   515         AbstractPlayer::changeState(newState);
   464     }
   516     }
   465 }
   517 }
   466 
   518 
   467 void MMF::AbstractMediaPlayer::updateMetaData()
   519 void MMF::AbstractMediaPlayer::updateMetaData()
   468 {
   520 {