diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/3rdparty/phonon/mmf/TODO.txt | 5 | ||||
-rw-r--r-- | src/3rdparty/phonon/mmf/abstractmediaplayer.cpp | 168 | ||||
-rw-r--r-- | src/3rdparty/phonon/mmf/abstractmediaplayer.h | 46 | ||||
-rw-r--r-- | src/3rdparty/phonon/mmf/abstractplayer.cpp | 71 | ||||
-rw-r--r-- | src/3rdparty/phonon/mmf/abstractplayer.h | 53 | ||||
-rw-r--r-- | src/3rdparty/phonon/mmf/dummyplayer.cpp | 13 | ||||
-rw-r--r-- | src/3rdparty/phonon/mmf/dummyplayer.h | 5 | ||||
-rw-r--r-- | src/3rdparty/phonon/mmf/mediaobject.cpp | 41 | ||||
-rw-r--r-- | src/3rdparty/phonon/mmf/mmf_videoplayer.cpp | 14 |
9 files changed, 223 insertions, 193 deletions
diff --git a/src/3rdparty/phonon/mmf/TODO.txt b/src/3rdparty/phonon/mmf/TODO.txt index 2c13632..a2b1865 100644 --- a/src/3rdparty/phonon/mmf/TODO.txt +++ b/src/3rdparty/phonon/mmf/TODO.txt @@ -3,8 +3,13 @@ TODO list for MMF Phonon backend The following items are in rough order of priority. +* Activating full-screen video playback in qmediaplayer causes the app to crash +This may be symptomatic of more general problems with re-sizing / re-positioning video while playing. + * Implement audio effects +* Support for playing "file:" URLs + * Support for network streaming playback The main question here is how best to implement the MIME type detection for streams. The OpenUrlL functions only take a URL, whereas the corresponding OpenFileL functions have overloads for filenames and for open RFile handles. This is because files support random access whereas streams do not. A naieve approach to MIME type detection for streams is as follows; is there a more efficient approach? 1. Open network connection diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp index 82dcd7c..8fe1e4d 100644 --- a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp +++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp @@ -16,6 +16,8 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. */ +#include <QUrl> + #include "abstractmediaplayer.h" #include "defs.h" #include "utils.h" @@ -37,11 +39,8 @@ const int NullMaxVolume = -1; //----------------------------------------------------------------------------- MMF::AbstractMediaPlayer::AbstractMediaPlayer() : - m_state(GroundState) - , m_error(NoError) - , m_playPending(false) + m_playPending(false) , m_tickTimer(new QTimer(this)) - , m_volume(InitialVolume) , m_mmfMaxVolume(NullMaxVolume) { connect(m_tickTimer.data(), SIGNAL(timeout()), this, SLOT(tick())); @@ -49,22 +48,13 @@ MMF::AbstractMediaPlayer::AbstractMediaPlayer() : MMF::AbstractMediaPlayer::AbstractMediaPlayer(const AbstractPlayer& player) : AbstractPlayer(player) - , m_state(GroundState) - , m_error(NoError) , m_playPending(false) , m_tickTimer(new QTimer(this)) - , m_volume(InitialVolume) , m_mmfMaxVolume(NullMaxVolume) { connect(m_tickTimer.data(), SIGNAL(timeout()), this, SLOT(tick())); } -MMF::AbstractMediaPlayer::~AbstractMediaPlayer() -{ - -} - - //----------------------------------------------------------------------------- // MediaObjectInterface //----------------------------------------------------------------------------- @@ -72,12 +62,11 @@ MMF::AbstractMediaPlayer::~AbstractMediaPlayer() void MMF::AbstractMediaPlayer::play() { TRACE_CONTEXT(AbstractMediaPlayer::play, EAudioApi); - TRACE_ENTRY("state %d", m_state); + TRACE_ENTRY("state %d", privateState()); - switch (m_state) { + switch (privateState()) { case GroundState: - m_error = NormalError; - changeState(ErrorState); + setError(NormalError); break; case LoadingState: @@ -102,25 +91,25 @@ void MMF::AbstractMediaPlayer::play() TRACE_PANIC(InvalidStatePanic); } - TRACE_EXIT("state %d", m_state); + TRACE_EXIT("state %d", privateState()); } void MMF::AbstractMediaPlayer::pause() { TRACE_CONTEXT(AbstractMediaPlayer::pause, EAudioApi); - TRACE_ENTRY("state %d", m_state); + TRACE_ENTRY("state %d", privateState()); m_playPending = false; - switch (m_state) { + switch (privateState()) { case GroundState: case LoadingState: - case StoppedState: case PausedState: case ErrorState: // Do nothing break; + case StoppedState: case PlayingState: case BufferingState: doPause(); @@ -133,17 +122,17 @@ void MMF::AbstractMediaPlayer::pause() TRACE_PANIC(InvalidStatePanic); } - TRACE_EXIT("state %d", m_state); + TRACE_EXIT("state %d", privateState()); } void MMF::AbstractMediaPlayer::stop() { TRACE_CONTEXT(AbstractMediaPlayer::stop, EAudioApi); - TRACE_ENTRY("state %d", m_state); + TRACE_ENTRY("state %d", privateState()); m_playPending = false; - switch (m_state) { + switch (privateState()) { case GroundState: case LoadingState: case StoppedState: @@ -164,7 +153,7 @@ void MMF::AbstractMediaPlayer::stop() TRACE_PANIC(InvalidStatePanic); } - TRACE_EXIT("state %d", m_state); + TRACE_EXIT("state %d", privateState()); } void MMF::AbstractMediaPlayer::seek(qint64 ms) @@ -172,7 +161,7 @@ void MMF::AbstractMediaPlayer::seek(qint64 ms) TRACE_CONTEXT(AbstractMediaPlayer::seek, EAudioApi); TRACE_ENTRY("state %d pos %Ld", state(), ms); - switch (m_state) { + switch (privateState()) { // Fallthrough all these case GroundState: case StoppedState: @@ -208,32 +197,13 @@ bool MMF::AbstractMediaPlayer::isSeekable() const void MMF::AbstractMediaPlayer::doSetTickInterval(qint32 interval) { TRACE_CONTEXT(AbstractMediaPlayer::doSetTickInterval, EAudioApi); - TRACE_ENTRY("state %d m_interval %d interval %d", m_state, tickInterval(), interval); + TRACE_ENTRY("state %d m_interval %d interval %d", privateState(), tickInterval(), interval); m_tickTimer->setInterval(interval); TRACE_EXIT_0(); } -Phonon::ErrorType MMF::AbstractMediaPlayer::errorType() const -{ - const Phonon::ErrorType result = (ErrorState == m_state) - ? m_error : NoError; - return result; -} - -QString MMF::AbstractMediaPlayer::errorString() const -{ - // TODO: put in proper error strings - QString result; - return result; -} - -Phonon::State MMF::AbstractMediaPlayer::state() const -{ - return phononState(m_state); -} - MediaSource MMF::AbstractMediaPlayer::source() const { return m_source; @@ -242,7 +212,7 @@ MediaSource MMF::AbstractMediaPlayer::source() const void MMF::AbstractMediaPlayer::setFileSource(const MediaSource &source, RFile& file) { TRACE_CONTEXT(AbstractMediaPlayer::setFileSource, EAudioApi); - TRACE_ENTRY("state %d source.type %d", m_state, source.type()); + TRACE_ENTRY("state %d source.type %d", privateState(), source.type()); close(); changeState(GroundState); @@ -255,25 +225,22 @@ void MMF::AbstractMediaPlayer::setFileSource(const MediaSource &source, RFile& f switch (m_source.type()) { case MediaSource::LocalFile: { - // TODO: work out whose responsibility it is to ensure that paths - // are Symbian-style, i.e. have backslashes for path delimiters. - // Until then, use this utility function... - //const QHBufC filename = Utils::symbianFilename(m_source.fileName()); - //TRAP(symbianErr, m_player->OpenFileL(*filename)); - - // Open using shared filehandle - // This is a temporary hack to work around KErrInUse from MMF - // client utility OpenFileL calls - //TRAP(symbianErr, m_player->OpenFileL(file)); - symbianErr = openFile(file); break; } case MediaSource::Url: { - TRACE_0("Source type not supported"); - // TODO: support opening URLs - symbianErr = KErrNotSupported; + const QUrl url(source.url()); + + if (url.scheme() == QLatin1String("file")) { + symbianErr = openFile(file); + } + else { + TRACE_0("Source type not supported"); + // TODO: support network URLs + symbianErr = KErrNotSupported; + } + break; } @@ -298,10 +265,7 @@ void MMF::AbstractMediaPlayer::setFileSource(const MediaSource &source, RFile& f changeState(LoadingState); } else { TRACE("error %d", symbianErr) - - // TODO: do something with the value of symbianErr? - m_error = NormalError; - changeState(ErrorState); + setError(NormalError); } TRACE_EXIT_0(); @@ -310,7 +274,7 @@ void MMF::AbstractMediaPlayer::setFileSource(const MediaSource &source, RFile& f void MMF::AbstractMediaPlayer::setNextSource(const MediaSource &source) { TRACE_CONTEXT(AbstractMediaPlayer::setNextSource, EAudioApi); - TRACE_ENTRY("state %d", m_state); + TRACE_ENTRY("state %d", privateState()); // TODO: handle 'next source' @@ -328,9 +292,9 @@ void MMF::AbstractMediaPlayer::setNextSource(const MediaSource &source) void MMF::AbstractMediaPlayer::volumeChanged(qreal volume) { TRACE_CONTEXT(AbstractMediaPlayer::volumeChanged, EAudioInternal); - TRACE_ENTRY("state %d", m_state); + TRACE_ENTRY("state %d", privateState()); - m_volume = volume; + AbstractPlayer::volumeChanged(volume); doVolumeChanged(); TRACE_EXIT_0(); @@ -339,7 +303,7 @@ void MMF::AbstractMediaPlayer::volumeChanged(qreal volume) void MMF::AbstractMediaPlayer::doVolumeChanged() { - switch (m_state) { + switch (privateState()) { case GroundState: case LoadingState: case ErrorState: @@ -353,8 +317,7 @@ void MMF::AbstractMediaPlayer::doVolumeChanged() const int err = setDeviceVolume(m_volume * m_mmfMaxVolume); if (KErrNone != err) { - m_error = NormalError; - changeState(ErrorState); + setError(NormalError); } break; } @@ -387,69 +350,46 @@ void MMF::AbstractMediaPlayer::maxVolumeChanged(int mmfMaxVolume) doVolumeChanged(); } -Phonon::State MMF::AbstractMediaPlayer::phononState() const -{ - return phononState(m_state); -} - -Phonon::State MMF::AbstractMediaPlayer::phononState(PrivateState state) +qint64 MMF::AbstractMediaPlayer::toMilliSeconds(const TTimeIntervalMicroSeconds &in) { - const Phonon::State phononState = - GroundState == state - ? Phonon::LoadingState - : static_cast<Phonon::State>(state); - - return phononState; + return in.Int64() / 1000; } void MMF::AbstractMediaPlayer::changeState(PrivateState newState) { - TRACE_CONTEXT(AbstractMediaPlayer::changeState, EAudioInternal); - TRACE_ENTRY("state %d newState %d", m_state, newState); + TRACE_CONTEXT(AbstractPlayer::changeState, EAudioInternal); + TRACE_ENTRY("state %d newState %d", privateState(), newState); // TODO: add some invariants to check that the transition is valid - const Phonon::State oldPhononState = phononState(m_state); + const Phonon::State oldPhononState = phononState(privateState()); const Phonon::State newPhononState = phononState(newState); if (oldPhononState != newPhononState) { TRACE("emit stateChanged(%d, %d)", newPhononState, oldPhononState); emit stateChanged(newPhononState, oldPhononState); } - m_state = newState; + setState(newState); - // Check whether play() was called while clip was being loaded. If so, - // playback should be started now if ( - LoadingState == oldPhononState - and StoppedState == newPhononState - and m_playPending - ) { - TRACE_0("play was called while loading; starting playback now"); - m_playPending = false; - play(); - } + LoadingState == oldPhononState + and StoppedState == newPhononState + ) { + // Ensure initial volume is set on MMF API before starting playback + doVolumeChanged(); + + // Check whether play() was called while clip was being loaded. If so, + // playback should be started now + if (m_playPending) { + TRACE_0("play was called while loading; starting playback now"); + m_playPending = false; + play(); + } + } TRACE_EXIT_0(); } -void MMF::AbstractMediaPlayer::setError(Phonon::ErrorType error) -{ - TRACE_CONTEXT(AbstractMediaPlayer::setError, EAudioInternal); - TRACE_ENTRY("state %d error %d", m_state, error); - - m_error = error; - changeState(ErrorState); - - TRACE_EXIT_0(); -} - -qint64 MMF::AbstractMediaPlayer::toMilliSeconds(const TTimeIntervalMicroSeconds &in) -{ - return in.Int64() / 1000; -} - - //----------------------------------------------------------------------------- // Slots //----------------------------------------------------------------------------- diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.h b/src/3rdparty/phonon/mmf/abstractmediaplayer.h index e69f325..698b899 100644 --- a/src/3rdparty/phonon/mmf/abstractmediaplayer.h +++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.h @@ -45,7 +45,6 @@ class AbstractMediaPlayer : public AbstractPlayer protected: AbstractMediaPlayer(); explicit AbstractMediaPlayer(const AbstractPlayer& player); - ~AbstractMediaPlayer(); public: // MediaObjectInterface @@ -54,9 +53,6 @@ public: virtual void stop(); virtual void seek(qint64 milliseconds); virtual bool isSeekable() const; - virtual Phonon::ErrorType errorType() const; - virtual QString errorString() const; - virtual Phonon::State state() const; virtual MediaSource source() const; virtual void setFileSource(const Phonon::MediaSource&, RFile&); virtual void setNextSource(const MediaSource &source); @@ -76,45 +72,17 @@ protected: virtual int openFile(RFile& file) = 0; virtual void close() = 0; + /** + * Changes state and emits stateChanged() + */ + virtual void changeState(PrivateState newState); + protected: bool tickTimerRunning() const; void startTickTimer(); void stopTickTimer(); void maxVolumeChanged(int maxVolume); - /** - * Defined private state enumeration in order to add GroundState - */ - enum PrivateState { - LoadingState = Phonon::LoadingState, - StoppedState = Phonon::StoppedState, - PlayingState = Phonon::PlayingState, - BufferingState = Phonon::BufferingState, - PausedState = Phonon::PausedState, - ErrorState = Phonon::ErrorState, - GroundState - }; - - /** - * Converts PrivateState into the corresponding Phonon::State - */ - Phonon::State phononState() const; - - /** - * Converts PrivateState into the corresponding Phonon::State - */ - static Phonon::State phononState(PrivateState state); - - /** - * Changes state and emits stateChanged() - */ - void changeState(PrivateState newState); - - /** - * Records error and changes state to ErrorState - */ - void setError(Phonon::ErrorType error); - static qint64 toMilliSeconds(const TTimeIntervalMicroSeconds &); private: @@ -127,9 +95,6 @@ private Q_SLOTS: void tick(); private: - PrivateState m_state; - Phonon::ErrorType m_error; - /** * This flag is set to true if play is called when the object is * in a Loading state. Once loading is complete, playback will @@ -139,7 +104,6 @@ private: QScopedPointer<QTimer> m_tickTimer; - qreal m_volume; int m_mmfMaxVolume; MediaSource m_source; diff --git a/src/3rdparty/phonon/mmf/abstractplayer.cpp b/src/3rdparty/phonon/mmf/abstractplayer.cpp index 6ed5d51..24ef20a 100644 --- a/src/3rdparty/phonon/mmf/abstractplayer.cpp +++ b/src/3rdparty/phonon/mmf/abstractplayer.cpp @@ -18,6 +18,7 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #include "abstractplayer.h" #include "defs.h" +#include "utils.h" QT_BEGIN_NAMESPACE @@ -31,6 +32,9 @@ using namespace Phonon::MMF; MMF::AbstractPlayer::AbstractPlayer() : m_videoOutput(0) + , m_volume(InitialVolume) + , m_state(GroundState) + , m_error(NoError) , m_tickInterval(DefaultTickInterval) , m_transitionTime(0) , m_prefinishMark(0) @@ -40,6 +44,9 @@ MMF::AbstractPlayer::AbstractPlayer() MMF::AbstractPlayer::AbstractPlayer(const AbstractPlayer& player) : m_videoOutput(player.m_videoOutput) + , m_volume(player.m_volume) + , m_state(GroundState) + , m_error(NoError) , m_tickInterval(player.tickInterval()) , m_transitionTime(player.transitionTime()) , m_prefinishMark(player.prefinishMark()) @@ -84,6 +91,16 @@ void MMF::AbstractPlayer::setTransitionTime(qint32 time) //----------------------------------------------------------------------------- +// VolumeObserver +//----------------------------------------------------------------------------- + +void MMF::AbstractPlayer::volumeChanged(qreal volume) +{ + m_volume = volume; +} + + +//----------------------------------------------------------------------------- // Video output //----------------------------------------------------------------------------- @@ -98,6 +115,60 @@ void MMF::AbstractPlayer::videoOutputChanged() // Default behaviour is empty - overridden by VideoPlayer } +void MMF::AbstractPlayer::setError(Phonon::ErrorType error) +{ + TRACE_CONTEXT(AbstractPlayer::setError, EAudioInternal); + TRACE_ENTRY("state %d error %d", m_state, error); + + m_error = error; + changeState(ErrorState); + + TRACE_EXIT_0(); +} + +Phonon::ErrorType MMF::AbstractPlayer::errorType() const +{ + const Phonon::ErrorType result = (ErrorState == m_state) + ? errorType() : NoError; + return result; +} + +QString MMF::AbstractPlayer::errorString() const +{ + // TODO: put in proper error strings + QString result; + return result; +} + +Phonon::State MMF::AbstractPlayer::phononState() const +{ + return phononState(m_state); +} + +Phonon::State MMF::AbstractPlayer::phononState(PrivateState state) +{ + const Phonon::State phononState = + GroundState == state + ? Phonon::LoadingState + : static_cast<Phonon::State>(state); + + return phononState; +} + +AbstractPlayer::PrivateState AbstractPlayer::privateState() const +{ + return m_state; +} + +Phonon::State MMF::AbstractPlayer::state() const +{ + return phononState(m_state); +} + +void MMF::AbstractPlayer::setState(PrivateState newState) +{ + m_state = newState; +} QT_END_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/abstractplayer.h b/src/3rdparty/phonon/mmf/abstractplayer.h index 72d0a3b..ec39ab1 100644 --- a/src/3rdparty/phonon/mmf/abstractplayer.h +++ b/src/3rdparty/phonon/mmf/abstractplayer.h @@ -75,9 +75,8 @@ public: virtual bool hasVideo() const = 0; virtual bool isSeekable() const = 0; virtual qint64 currentTime() const = 0; - virtual Phonon::State state() const = 0; - virtual QString errorString() const = 0; - virtual Phonon::ErrorType errorType() const = 0; + virtual Phonon::ErrorType errorType() const; + virtual QString errorString() const; virtual qint64 totalTime() const = 0; virtual Phonon::MediaSource source() const = 0; // This is a temporary hack to work around KErrInUse from MMF @@ -86,8 +85,17 @@ public: virtual void setFileSource(const Phonon::MediaSource&, RFile&) = 0; virtual void setNextSource(const Phonon::MediaSource &) = 0; + // VolumeObserver + virtual void volumeChanged(qreal volume); + void setVideoOutput(VideoOutput* videoOutput); + /** + * Records error and changes state to ErrorState + */ + void setError(Phonon::ErrorType error); + + Phonon::State state() const; Q_SIGNALS: void totalTimeChanged(qint64 length); void finished(); @@ -97,16 +105,53 @@ Q_SIGNALS: protected: + /** + * Defined private state enumeration in order to add GroundState + */ + enum PrivateState { + LoadingState = Phonon::LoadingState, + StoppedState = Phonon::StoppedState, + PlayingState = Phonon::PlayingState, + BufferingState = Phonon::BufferingState, + PausedState = Phonon::PausedState, + ErrorState = Phonon::ErrorState, + GroundState + }; + + /** + * Converts PrivateState into the corresponding Phonon::State + */ + Phonon::State phononState() const; + + /** + * Converts PrivateState into the corresponding Phonon::State + */ + static Phonon::State phononState(PrivateState state); + virtual void videoOutputChanged(); + PrivateState privateState() const; + + virtual void changeState(PrivateState newState) = 0; + + /** + * Modifies m_state directly. Typically you want to call changeState(), + * which performs the business logic. + */ + void setState(PrivateState newState); + private: virtual void doSetTickInterval(qint32 interval) = 0; protected: // Not owned VideoOutput* m_videoOutput; - + + qreal m_volume; + private: + PrivateState m_state; + Phonon::ErrorType m_error; qint32 m_tickInterval; qint32 m_transitionTime; qint32 m_prefinishMark; diff --git a/src/3rdparty/phonon/mmf/dummyplayer.cpp b/src/3rdparty/phonon/mmf/dummyplayer.cpp index dc55af7..4c059c4 100644 --- a/src/3rdparty/phonon/mmf/dummyplayer.cpp +++ b/src/3rdparty/phonon/mmf/dummyplayer.cpp @@ -115,16 +115,6 @@ void MMF::DummyPlayer::setNextSource(const MediaSource &) //----------------------------------------------------------------------------- -// VolumeObserver -//----------------------------------------------------------------------------- - -void MMF::DummyPlayer::volumeChanged(qreal) -{ - -} - - -//----------------------------------------------------------------------------- // AbstractPlayer //----------------------------------------------------------------------------- @@ -133,6 +123,9 @@ void MMF::DummyPlayer::doSetTickInterval(qint32) } +void MMF::DummyPlayer::changeState(PrivateState) +{ +} QT_END_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/dummyplayer.h b/src/3rdparty/phonon/mmf/dummyplayer.h index b2725df..9ff9f78 100644 --- a/src/3rdparty/phonon/mmf/dummyplayer.h +++ b/src/3rdparty/phonon/mmf/dummyplayer.h @@ -62,12 +62,11 @@ public: virtual void setFileSource(const Phonon::MediaSource&, RFile&); virtual void setNextSource(const MediaSource &source); - // VolumeObserver - virtual void volumeChanged(qreal volume); - // AbstractPlayer virtual void doSetTickInterval(qint32 interval); +protected: + virtual void changeState(PrivateState newState); }; } } diff --git a/src/3rdparty/phonon/mmf/mediaobject.cpp b/src/3rdparty/phonon/mmf/mediaobject.cpp index 5a5540c..0591e05 100644 --- a/src/3rdparty/phonon/mmf/mediaobject.cpp +++ b/src/3rdparty/phonon/mmf/mediaobject.cpp @@ -28,6 +28,7 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #include "mediaobject.h" #include <QDir> +#include <QUrl> QT_BEGIN_NAMESPACE @@ -233,6 +234,8 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) const bool oldPlayerHasVideo = oldPlayer->hasVideo(); const bool oldPlayerSeekable = oldPlayer->isSeekable(); + Phonon::ErrorType error = NoError; + // Determine media type switch (source.type()) { case MediaSource::LocalFile: @@ -240,26 +243,23 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) break; case MediaSource::Url: - // TODO: support detection of media type from HTTP streams - TRACE_0("Network streaming not supported yet"); - /* - * TODO: handle error - * - m_error = NormalError; - changeState(ErrorState); - */ + { + const QUrl url(source.url()); + if (url.scheme() == QLatin1String("file")) { + mediaType = fileMediaType(url.toLocalFile()); + } + else { + TRACE_0("Network streaming not supported yet"); + error = NormalError; + } + } break; case MediaSource::Invalid: case MediaSource::Disc: case MediaSource::Stream: TRACE_0("Unsupported media type"); - /* - * TODO: handle error - * - m_error = NormalError; - changeState(ErrorState); - */ + error = NormalError; break; case MediaSource::Empty: @@ -281,12 +281,8 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) } else { newPlayer = new DummyPlayer(); } - /* - * TODO: handle error? - * - m_error = NormalError; - changeState(ErrorState); - */ + + newPlayer->setError(NormalError); break; case MediaTypeAudio: @@ -321,6 +317,11 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) connect(m_player.data(), SIGNAL(finished()), SIGNAL(finished())); connect(m_player.data(), SIGNAL(tick(qint64)), SIGNAL(tick(qint64))); + if (error != NoError ) { + newPlayer = new DummyPlayer(); + newPlayer->setError(error); + } + TRACE_EXIT_0(); } diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp index 8a38b76..64e6568 100644 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp +++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp @@ -147,10 +147,22 @@ void MMF::VideoPlayer::doStop() void MMF::VideoPlayer::doSeek(qint64 ms) { TRACE_CONTEXT(VideoPlayer::doSeek, EVideoApi); + + bool wasPlaying = false; + if(state() == PlayingState) { + // The call to SetPositionL does not have any effect if playback is + // ongoing, so we pause before seeking. + doPause(); + wasPlaying = true; + } TRAPD(err, m_player->SetPositionL(TTimeIntervalMicroSeconds(ms * 1000))); - if (KErrNone != err) { + if(KErrNone == err) { + if(wasPlaying) + doPlay(); + } + else { TRACE("SetPositionL error %d", err); setError(NormalError); } |