summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--demos/embedded/fluidlauncher/fluidlauncher.pro1
-rw-r--r--src/3rdparty/phonon/mmf/TODO.txt5
-rw-r--r--src/3rdparty/phonon/mmf/abstractmediaplayer.cpp168
-rw-r--r--src/3rdparty/phonon/mmf/abstractmediaplayer.h46
-rw-r--r--src/3rdparty/phonon/mmf/abstractplayer.cpp71
-rw-r--r--src/3rdparty/phonon/mmf/abstractplayer.h53
-rw-r--r--src/3rdparty/phonon/mmf/dummyplayer.cpp13
-rw-r--r--src/3rdparty/phonon/mmf/dummyplayer.h5
-rw-r--r--src/3rdparty/phonon/mmf/mediaobject.cpp41
-rw-r--r--src/3rdparty/phonon/mmf/mmf_videoplayer.cpp14
-rw-r--r--tests/auto/mediaobject/tst_mediaobject.cpp7
11 files changed, 230 insertions, 194 deletions
diff --git a/demos/embedded/fluidlauncher/fluidlauncher.pro b/demos/embedded/fluidlauncher/fluidlauncher.pro
index 62791f1..408bf53 100644
--- a/demos/embedded/fluidlauncher/fluidlauncher.pro
+++ b/demos/embedded/fluidlauncher/fluidlauncher.pro
@@ -143,6 +143,7 @@ symbian {
}
contains(QT_CONFIG, phonon) {
+ executables.sources += qmediaplayer.exe
resource.sources += $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/qmediaplayer.rsc
}
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);
}
diff --git a/tests/auto/mediaobject/tst_mediaobject.cpp b/tests/auto/mediaobject/tst_mediaobject.cpp
index 556e465..16b2611 100644
--- a/tests/auto/mediaobject/tst_mediaobject.cpp
+++ b/tests/auto/mediaobject/tst_mediaobject.cpp
@@ -89,7 +89,7 @@ const qint64 SEEK_BACKWARDS = 2000;
const qint64 ALLOWED_TIME_FOR_SEEKING = 1500; // 1.5s
const qint64 SEEKING_TOLERANCE = 250;
#else
-#if defined(Q_OS_WIN) || defined(Q_OS_MAC)
+#if defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(Q_OS_SYMBIAN)
#define MEDIA_FILE "/sax.mp3"
#define MEDIA_FILEPATH ":/media/sax.mp3"
#else
@@ -207,6 +207,11 @@ void tst_MediaObject::stateChanged(Phonon::State newstate, Phonon::State oldstat
void tst_MediaObject::testPlayFromResource()
{
+#ifdef Q_OS_SYMBIAN
+ QSKIP("Not implemented yet.", SkipAll);
+ return;
+#endif
+
QFile file(MEDIA_FILEPATH);
MediaObject media;
media.setCurrentSource(&file);