summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/phonon/mmf
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/phonon/mmf')
-rw-r--r--src/3rdparty/phonon/mmf/abstractmediaplayer.cpp58
-rw-r--r--src/3rdparty/phonon/mmf/abstractmediaplayer.h10
-rw-r--r--src/3rdparty/phonon/mmf/abstractplayer.cpp32
-rw-r--r--src/3rdparty/phonon/mmf/abstractplayer.h12
-rw-r--r--src/3rdparty/phonon/mmf/ancestormovemonitor.cpp175
-rw-r--r--src/3rdparty/phonon/mmf/ancestormovemonitor.h95
-rw-r--r--src/3rdparty/phonon/mmf/audioplayer.cpp21
-rw-r--r--src/3rdparty/phonon/mmf/audioplayer.h4
-rw-r--r--src/3rdparty/phonon/mmf/backend.cpp7
-rw-r--r--src/3rdparty/phonon/mmf/backend.h7
-rw-r--r--src/3rdparty/phonon/mmf/dummyplayer.cpp9
-rw-r--r--src/3rdparty/phonon/mmf/dummyplayer.h4
-rw-r--r--src/3rdparty/phonon/mmf/mediaobject.cpp15
-rw-r--r--src/3rdparty/phonon/mmf/mmf_videoplayer.cpp16
-rw-r--r--src/3rdparty/phonon/mmf/mmf_videoplayer.h4
-rw-r--r--src/3rdparty/phonon/mmf/videooutput.cpp30
-rw-r--r--src/3rdparty/phonon/mmf/videooutput.h15
-rw-r--r--src/3rdparty/phonon/mmf/videowidget.cpp5
-rw-r--r--src/3rdparty/phonon/mmf/videowidget.h3
19 files changed, 458 insertions, 64 deletions
diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp
index af2c31e..f2efaa0 100644
--- a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp
+++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp
@@ -318,7 +318,8 @@ void MMF::AbstractMediaPlayer::doVolumeChanged()
case PausedState:
case PlayingState:
case BufferingState: {
- const int err = setDeviceVolume(m_volume * m_mmfMaxVolume);
+ const qreal volume = (m_volume * m_mmfMaxVolume) + 0.5;
+ const int err = setDeviceVolume(volume);
if (KErrNone != err) {
setError(NormalError);
@@ -359,26 +360,27 @@ qint64 MMF::AbstractMediaPlayer::toMilliSeconds(const TTimeIntervalMicroSeconds
return in.Int64() / 1000;
}
-void MMF::AbstractMediaPlayer::changeState(PrivateState newState)
+//-----------------------------------------------------------------------------
+// Slots
+//-----------------------------------------------------------------------------
+
+void MMF::AbstractMediaPlayer::tick()
{
- TRACE_CONTEXT(AbstractPlayer::changeState, EAudioInternal);
- TRACE_ENTRY("state %d newState %d", privateState(), newState);
+ // For the MWC compiler, we need to qualify the base class.
+ emit MMF::AbstractPlayer::tick(currentTime());
+}
- // TODO: add some invariants to check that the transition is valid
+void MMF::AbstractMediaPlayer::changeState(PrivateState newState)
+{
+ TRACE_CONTEXT(AbstractMediaPlayer::changeState, EAudioInternal);
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);
- }
- setState(newState);
+ // TODO: add some invariants to check that the transition is valid
+ AbstractPlayer::changeState(newState);
- if (
- LoadingState == oldPhononState
- and StoppedState == newPhononState
- ) {
+ if (LoadingState == oldPhononState && StoppedState == newPhononState) {
// Ensure initial volume is set on MMF API before starting playback
doVolumeChanged();
@@ -390,18 +392,28 @@ void MMF::AbstractMediaPlayer::changeState(PrivateState newState)
play();
}
}
-
- TRACE_EXIT_0();
}
-//-----------------------------------------------------------------------------
-// Slots
-//-----------------------------------------------------------------------------
-
-void MMF::AbstractMediaPlayer::tick()
+void MMF::AbstractMediaPlayer::updateMetaData()
{
- // For the MWC compiler, we need to qualify the base class.
- emit MMF::AbstractPlayer::tick(currentTime());
+ TRACE_CONTEXT(AbstractMediaPlayer::updateMetaData, EAudioInternal);
+ TRACE_ENTRY_0();
+
+ m_metaData.clear();
+
+ const int numberOfEntries = numberOfMetaDataEntries();
+ for(int i=0; i<numberOfEntries; ++i) {
+ const QPair<QString, QString> entry = metaDataEntry(i);
+
+ // Note that we capitalize the key, as required by the Ogg Vorbis
+ // metadata standard to which Phonon adheres:
+ // http://xiph.org/vorbis/doc/v-comment.html
+ m_metaData.insert(entry.first.toUpper(), entry.second);
+ }
+
+ emit metaDataChanged(m_metaData);
+
+ TRACE_EXIT_0();
}
QT_END_NAMESPACE
diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.h b/src/3rdparty/phonon/mmf/abstractmediaplayer.h
index 698b899..cff7bab 100644
--- a/src/3rdparty/phonon/mmf/abstractmediaplayer.h
+++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.h
@@ -71,12 +71,12 @@ protected:
virtual int setDeviceVolume(int mmfVolume) = 0;
virtual int openFile(RFile& file) = 0;
virtual void close() = 0;
-
- /**
- * Changes state and emits stateChanged()
- */
virtual void changeState(PrivateState newState);
+ void updateMetaData();
+ virtual int numberOfMetaDataEntries() const = 0;
+ virtual QPair<QString, QString> metaDataEntry(int index) const = 0;
+
protected:
bool tickTimerRunning() const;
void startTickTimer();
@@ -109,6 +109,8 @@ private:
MediaSource m_source;
MediaSource m_nextSource;
+ QMultiMap<QString, QString> m_metaData;
+
};
}
}
diff --git a/src/3rdparty/phonon/mmf/abstractplayer.cpp b/src/3rdparty/phonon/mmf/abstractplayer.cpp
index e3c0ecb..de2722d 100644
--- a/src/3rdparty/phonon/mmf/abstractplayer.cpp
+++ b/src/3rdparty/phonon/mmf/abstractplayer.cpp
@@ -118,12 +118,14 @@ void MMF::AbstractPlayer::videoOutputChanged()
// Default behaviour is empty - overridden by VideoPlayer
}
-void MMF::AbstractPlayer::setError(Phonon::ErrorType error)
+void MMF::AbstractPlayer::setError(Phonon::ErrorType error,
+ const QString &errorMessage)
{
TRACE_CONTEXT(AbstractPlayer::setError, EAudioInternal);
TRACE_ENTRY("state %d error %d", m_state, error);
m_error = error;
+ m_errorString = errorMessage;
changeState(ErrorState);
TRACE_EXIT_0();
@@ -138,9 +140,7 @@ Phonon::ErrorType MMF::AbstractPlayer::errorType() const
QString MMF::AbstractPlayer::errorString() const
{
- // TODO: put in proper error strings
- QString result;
- return result;
+ return m_errorString;
}
Phonon::State MMF::AbstractPlayer::phononState() const
@@ -173,5 +173,29 @@ void MMF::AbstractPlayer::setState(PrivateState newState)
m_state = newState;
}
+void MMF::AbstractPlayer::changeState(PrivateState 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(privateState());
+
+ // We need to change the state before we emit stateChanged(), because
+ // some user code, for instance the mediaplayer, switch on MediaObject's
+ // state.
+ setState(newState);
+
+ const Phonon::State newPhononState = phononState(newState);
+
+ if (oldPhononState != newPhononState) {
+ TRACE("emit stateChanged(%d, %d)", newPhononState, oldPhononState);
+ emit stateChanged(newPhononState, oldPhononState);
+ }
+
+ TRACE_EXIT_0();
+}
+
QT_END_NAMESPACE
diff --git a/src/3rdparty/phonon/mmf/abstractplayer.h b/src/3rdparty/phonon/mmf/abstractplayer.h
index 08558cf..66496cc 100644
--- a/src/3rdparty/phonon/mmf/abstractplayer.h
+++ b/src/3rdparty/phonon/mmf/abstractplayer.h
@@ -93,16 +93,18 @@ public:
/**
* Records error and changes state to ErrorState
*/
- void setError(Phonon::ErrorType error);
+ void setError(Phonon::ErrorType error,
+ const QString &errorMessage = QString());
Phonon::State state() const;
+
Q_SIGNALS:
void totalTimeChanged(qint64 length);
void finished();
void tick(qint64 time);
void stateChanged(Phonon::State oldState,
Phonon::State newState);
-
+ void metaDataChanged(const QMultiMap<QString, QString>& metaData);
protected:
/**
@@ -132,7 +134,10 @@ protected:
PrivateState privateState() const;
- virtual void changeState(PrivateState newState) = 0;
+ /**
+ * Changes state and emits stateChanged()
+ */
+ virtual void changeState(PrivateState newState);
/**
* Modifies m_state directly. Typically you want to call changeState(),
@@ -152,6 +157,7 @@ protected:
private:
PrivateState m_state;
Phonon::ErrorType m_error;
+ QString m_errorString;
qint32 m_tickInterval;
qint32 m_transitionTime;
qint32 m_prefinishMark;
diff --git a/src/3rdparty/phonon/mmf/ancestormovemonitor.cpp b/src/3rdparty/phonon/mmf/ancestormovemonitor.cpp
new file mode 100644
index 0000000..0447d57
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/ancestormovemonitor.cpp
@@ -0,0 +1,175 @@
+/* This file is part of the KDE project.
+
+Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+
+This library is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 2.1 or 3 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this library. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "ancestormovemonitor.h"
+#include "utils.h"
+#include "videooutput.h"
+
+#include <QCoreApplication>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon::MMF;
+
+/*! \class MMF::AncestorMoveMonitor
+ \internal
+ \brief Class which installs a global event filter, and listens for move
+ events which may affect the absolute position of widgets registered with
+ the monitor
+ See QTBUG-4956
+*/
+
+//-----------------------------------------------------------------------------
+// Constructor / destructor
+//-----------------------------------------------------------------------------
+
+AncestorMoveMonitor::AncestorMoveMonitor(QObject *parent)
+ : QObject(parent)
+{
+ QCoreApplication::instance()->installEventFilter(this);
+}
+
+AncestorMoveMonitor::~AncestorMoveMonitor()
+{
+ QCoreApplication::instance()->removeEventFilter(this);
+}
+
+
+//-----------------------------------------------------------------------------
+// Public functions
+//-----------------------------------------------------------------------------
+
+void AncestorMoveMonitor::registerTarget(VideoOutput *target)
+{
+ TRACE_CONTEXT(AncestorMoveMonitor::registerTarget, EVideoInternal);
+ TRACE_ENTRY("target 0x%08x", target);
+
+ // First un-register the target, in case this is being called as a result
+ // of re-parenting. This is not the most efficient way to update the
+ // target hash, but since this is not likely to be a frequent operation,
+ // simplicity is preferred over outright speed. In any case, re-parenting
+ // of the video widget leads to re-creation of native windows, which is
+ // likely to take far more processing than any implementation of this
+ // function.
+ unRegisterTarget(target);
+
+ QWidget *ancestor = target->parentWidget();
+ while(ancestor) {
+ const Hash::iterator it = m_hash.find(ancestor);
+ if(m_hash.end() == it) {
+ TargetList targetList;
+ targetList.append(target);
+ m_hash.insert(ancestor, targetList);
+ } else {
+ TargetList& targetList = it.value();
+ Q_ASSERT(targetList.indexOf(target) == -1);
+ targetList.append(target);
+ }
+ ancestor = ancestor->parentWidget();
+ }
+
+ dump();
+
+ TRACE_EXIT_0();
+}
+
+void AncestorMoveMonitor::unRegisterTarget(VideoOutput *target)
+{
+ TRACE_CONTEXT(AncestorMoveMonitor::unRegisterTarget, EVideoInternal);
+ TRACE_ENTRY("target 0x%08x", target);
+
+ Hash::iterator it = m_hash.begin();
+ while(it != m_hash.end()) {
+ TargetList& targetList = it.value();
+ const int index = targetList.indexOf(target);
+ if(index != -1)
+ targetList.removeAt(index);
+ if(targetList.count())
+ ++it;
+ else
+ it = m_hash.erase(it);
+ }
+
+ dump();
+
+ TRACE_EXIT_0();
+}
+
+bool AncestorMoveMonitor::eventFilter(QObject *watched, QEvent *event)
+{
+ TRACE_CONTEXT(AncestorMoveMonitor::eventFilter, EVideoInternal);
+
+ if(event->type() == QEvent::Move || event->type() == QEvent::ParentChange) {
+
+ //TRACE_ENTRY("watched 0x%08x event.type %d", watched, event->type());
+
+ const Hash::const_iterator it = m_hash.find(watched);
+ if(it != m_hash.end()) {
+ const TargetList& targetList = it.value();
+ VideoOutput* target = 0;
+ foreach(target, targetList) {
+ switch (event->type()) {
+
+ case QEvent::Move:
+ // Notify the target that its ancestor has moved
+ target->ancestorMoved();
+ break;
+
+ case QEvent::ParentChange:
+ // Update ancestor list for the target
+ registerTarget(target);
+ break;
+
+ default:
+ Q_ASSERT(false);
+ }
+ }
+ }
+
+ //TRACE_EXIT_0();
+ }
+
+ // The event is never consumed by this filter
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Private functions
+//-----------------------------------------------------------------------------
+
+void AncestorMoveMonitor::dump()
+{
+#ifndef QT_NO_DEBUG
+ TRACE_CONTEXT(AncestorMoveMonitor::dump, EVideoInternal);
+ for(Hash::const_iterator it = m_hash.begin();
+ it != m_hash.end(); ++it) {
+ const QObject *ancestor = it.key();
+ TRACE("ancestor 0x%08x", ancestor);
+ const TargetList& targetList = it.value();
+ VideoOutput* target = 0;
+ foreach(target, targetList) {
+ TRACE(" target 0x%08x", target);
+ }
+ }
+#endif
+}
+
+
+
+QT_END_NAMESPACE
+
diff --git a/src/3rdparty/phonon/mmf/ancestormovemonitor.h b/src/3rdparty/phonon/mmf/ancestormovemonitor.h
new file mode 100644
index 0000000..0e681aa
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/ancestormovemonitor.h
@@ -0,0 +1,95 @@
+/* This file is part of the KDE project.
+
+Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+
+This library is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 2.1 or 3 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this library. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef PHONON_MMF_ANCESTORMOVEMONITOR_H
+#define PHONON_MMF_ANCESTORMOVEMONITOR_H
+
+#include <QObject>
+#include <QHash>
+#include <QList>
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace MMF
+{
+class VideoOutput;
+
+class AncestorMoveMonitor : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit AncestorMoveMonitor(QObject *parent);
+ ~AncestorMoveMonitor();
+
+ /**
+ * Register target widget for notification.
+ *
+ * The widget receives an ancestorMoveEvent callback when a move event
+ * is delivered to any of its ancestors:
+ *
+ * If the target is already registered, this function causes its
+ * ancestor list to be updated - therefore it should be called when
+ * the target receives a ParentChange event.
+ */
+ void registerTarget(VideoOutput *target);
+
+ /**
+ * Remove target from the monitor.
+ *
+ * The target will no longer receive notification when move events are
+ * delivered to its ancestors.
+ */
+ void unRegisterTarget(VideoOutput *target);
+
+protected:
+ /**
+ * Function which receives events from the global event filter.
+ */
+ bool eventFilter(QObject *watched, QEvent *event);
+
+ void dump();
+
+private:
+ /**
+ * List of registered target widgets which descend from a given
+ * ancestor.
+ *
+ * Note that the members of the list should be non-redundant; this
+ * invariant is checked in debug builds. Semantically, the value is
+ * therefore a set, however we use QList rather than QSet for
+ * efficiency of iteration.
+ */
+ typedef QList<VideoOutput *> TargetList;
+
+ /**
+ * Map from widget on which the move event occurs, to widgets which
+ * descend from it and therefore need to be notified.
+ */
+ typedef QHash<QObject *, TargetList> Hash;
+ Hash m_hash;
+
+};
+}
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/3rdparty/phonon/mmf/audioplayer.cpp b/src/3rdparty/phonon/mmf/audioplayer.cpp
index 1d259a8..8fccfe6 100644
--- a/src/3rdparty/phonon/mmf/audioplayer.cpp
+++ b/src/3rdparty/phonon/mmf/audioplayer.cpp
@@ -182,8 +182,8 @@ void MMF::AudioPlayer::MapcInitComplete(TInt aError,
if (KErrNone == aError) {
maxVolumeChanged(m_player->MaxVolume());
-
emit totalTimeChanged(totalTime());
+ updateMetaData();
changeState(StoppedState);
} else {
// TODO: set different error states according to value of aError?
@@ -251,5 +251,24 @@ void MMF::AudioPlayer::MaloLoadingComplete()
#endif // QT_PHONON_MMF_AUDIO_DRM
+//-----------------------------------------------------------------------------
+// Private functions
+//-----------------------------------------------------------------------------
+
+int MMF::AudioPlayer::numberOfMetaDataEntries() const
+{
+ int numberOfEntries = 0;
+ m_player->GetNumberOfMetaDataEntries(numberOfEntries); // ignoring return code
+ return numberOfEntries;
+}
+
+QPair<QString, QString> MMF::AudioPlayer::metaDataEntry(int index) const
+{
+ CMMFMetaDataEntry *entry = 0;
+ QT_TRAP_THROWING(entry = m_player->GetMetaDataEntryL(index));
+ return QPair<QString, QString>(qt_TDesC2QString(entry->Name()), qt_TDesC2QString(entry->Value()));
+}
+
+
QT_END_NAMESPACE
diff --git a/src/3rdparty/phonon/mmf/audioplayer.h b/src/3rdparty/phonon/mmf/audioplayer.h
index 60ef436..bc60076 100644
--- a/src/3rdparty/phonon/mmf/audioplayer.h
+++ b/src/3rdparty/phonon/mmf/audioplayer.h
@@ -94,6 +94,10 @@ public:
private:
void construct();
+ // AbstractMediaPlayer
+ virtual int numberOfMetaDataEntries() const;
+ virtual QPair<QString, QString> metaDataEntry(int index) const;
+
private:
/**
* Using CPlayerType typedef in order to be able to easily switch between
diff --git a/src/3rdparty/phonon/mmf/backend.cpp b/src/3rdparty/phonon/mmf/backend.cpp
index f542ec9..cac27e3 100644
--- a/src/3rdparty/phonon/mmf/backend.cpp
+++ b/src/3rdparty/phonon/mmf/backend.cpp
@@ -24,6 +24,7 @@ along with this library. If not, see <http://www.gnu.org/licenses/>.
#include <apmstd.h> // for TDataType
#include "abstractaudioeffect.h"
+#include "ancestormovemonitor.h"
#include "audiooutput.h"
#include "audioplayer.h"
#include "backend.h"
@@ -45,7 +46,9 @@ using namespace Phonon::MMF;
\internal
*/
-Backend::Backend(QObject *parent) : QObject(parent)
+Backend::Backend(QObject *parent)
+ : QObject(parent)
+ , m_ancestorMoveMonitor(new AncestorMoveMonitor(this))
{
TRACE_CONTEXT(Backend::Backend, EBackend);
TRACE_ENTRY_0();
@@ -87,7 +90,7 @@ QObject *Backend::createObject(BackendInterface::Class c, QObject *parent, const
return EffectFactory::createAudioEffect(effect, parent);
}
case VideoWidgetClass:
- result = new VideoWidget(qobject_cast<QWidget *>(parent));
+ result = new VideoWidget(m_ancestorMoveMonitor.data(), qobject_cast<QWidget *>(parent));
break;
default:
diff --git a/src/3rdparty/phonon/mmf/backend.h b/src/3rdparty/phonon/mmf/backend.h
index 1886ae6..9e3d3b3 100644
--- a/src/3rdparty/phonon/mmf/backend.h
+++ b/src/3rdparty/phonon/mmf/backend.h
@@ -19,8 +19,11 @@ along with this library. If not, see <http://www.gnu.org/licenses/>.
#ifndef PHONON_MMF_BACKEND_H
#define PHONON_MMF_BACKEND_H
+#include "ancestormovemonitor.h"
+
#include <Phonon/MediaSource>
#include <Phonon/BackendInterface>
+#include <QScopedPointer>
QT_BEGIN_NAMESPACE
@@ -47,6 +50,10 @@ public:
Q_SIGNALS:
void objectDescriptionChanged(ObjectDescriptionType);
+
+private:
+ QScopedPointer<AncestorMoveMonitor> m_ancestorMoveMonitor;
+
};
}
}
diff --git a/src/3rdparty/phonon/mmf/dummyplayer.cpp b/src/3rdparty/phonon/mmf/dummyplayer.cpp
index bd21d20..e6f3855 100644
--- a/src/3rdparty/phonon/mmf/dummyplayer.cpp
+++ b/src/3rdparty/phonon/mmf/dummyplayer.cpp
@@ -87,11 +87,6 @@ qint64 MMF::DummyPlayer::currentTime() const
return 0;
}
-QString MMF::DummyPlayer::errorString() const
-{
- return QString();
-}
-
Phonon::ErrorType MMF::DummyPlayer::errorType() const
{
return Phonon::NoError;
@@ -127,9 +122,5 @@ 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 9ff9f78..c6270c9 100644
--- a/src/3rdparty/phonon/mmf/dummyplayer.h
+++ b/src/3rdparty/phonon/mmf/dummyplayer.h
@@ -54,7 +54,6 @@ public:
virtual bool isSeekable() const;
virtual qint64 currentTime() const;
virtual Phonon::State state() const;
- virtual QString errorString() const;
virtual Phonon::ErrorType errorType() const;
virtual qint64 totalTime() const;
virtual MediaSource source() const;
@@ -64,9 +63,6 @@ public:
// 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 29ac2df..f004fd7 100644
--- a/src/3rdparty/phonon/mmf/mediaobject.cpp
+++ b/src/3rdparty/phonon/mmf/mediaobject.cpp
@@ -239,6 +239,7 @@ void MMF::MediaObject::createPlayer(const MediaSource &source)
const bool oldPlayerSeekable = oldPlayer->isSeekable();
Phonon::ErrorType error = NoError;
+ QString errorMessage;
// Determine media type
switch (source.type()) {
@@ -253,7 +254,7 @@ void MMF::MediaObject::createPlayer(const MediaSource &source)
mediaType = fileMediaType(url.toLocalFile());
}
else {
- TRACE_0("Network streaming not supported yet");
+ errorMessage = QLatin1String("Network streaming not supported yet");
error = NormalError;
}
}
@@ -286,7 +287,8 @@ void MMF::MediaObject::createPlayer(const MediaSource &source)
newPlayer = new DummyPlayer();
}
- newPlayer->setError(NormalError);
+ error = NormalError;
+ errorMessage = tr("Media type could not be determined");
break;
case MediaTypeAudio:
@@ -320,10 +322,13 @@ void MMF::MediaObject::createPlayer(const MediaSource &source)
connect(m_player.data(), SIGNAL(stateChanged(Phonon::State, Phonon::State)), SIGNAL(stateChanged(Phonon::State, Phonon::State)));
connect(m_player.data(), SIGNAL(finished()), SIGNAL(finished()));
connect(m_player.data(), SIGNAL(tick(qint64)), SIGNAL(tick(qint64)));
+ connect(m_player.data(), SIGNAL(metaDataChanged(const QMultiMap<QString, QString>&)), SIGNAL(metaDataChanged(const QMultiMap<QString, QString>&)));
- if (error != NoError ) {
- newPlayer = new DummyPlayer();
- newPlayer->setError(error);
+ // We need to call setError() after doing the connects, otherwise the
+ // error won't be received.
+ if (error != NoError) {
+ Q_ASSERT(m_player);
+ m_player->setError(error, errorMessage);
}
TRACE_EXIT_0();
diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp
index d1d2337..ba7d005 100644
--- a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp
+++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp
@@ -110,6 +110,9 @@ MMF::VideoPlayer::~VideoPlayer()
TRACE_CONTEXT(VideoPlayer::~VideoPlayer, EVideoApi);
TRACE_ENTRY_0();
+ if (m_videoOutput)
+ m_videoOutput->setObserver(0);
+
TRACE_EXIT_0();
}
@@ -487,6 +490,19 @@ bool MMF::VideoPlayer::getNativeWindowSystemHandles()
TRACE_RETURN("changed %d", changed);
}
+int MMF::VideoPlayer::numberOfMetaDataEntries() const
+{
+ int numberOfEntries = 0;
+ TRAP_IGNORE(numberOfEntries = m_player->NumberOfMetaDataEntriesL());
+ return numberOfEntries;
+}
+
+QPair<QString, QString> MMF::VideoPlayer::metaDataEntry(int index) const
+{
+ CMMFMetaDataEntry *entry = 0;
+ QT_TRAP_THROWING(entry = m_player->MetaDataEntryL(index));
+ return QPair<QString, QString>(qt_TDesC2QString(entry->Name()), qt_TDesC2QString(entry->Value()));
+}
QT_END_NAMESPACE
diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.h b/src/3rdparty/phonon/mmf/mmf_videoplayer.h
index 8072404..fa4e59b 100644
--- a/src/3rdparty/phonon/mmf/mmf_videoplayer.h
+++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.h
@@ -86,6 +86,10 @@ private:
void updateMmfOutput();
+ // AbstractMediaPlayer
+ virtual int numberOfMetaDataEntries() const;
+ virtual QPair<QString, QString> metaDataEntry(int index) const;
+
private:
QScopedPointer<CVideoPlayerUtility> m_player;
diff --git a/src/3rdparty/phonon/mmf/videooutput.cpp b/src/3rdparty/phonon/mmf/videooutput.cpp
index f0393a7..5288b4d 100644
--- a/src/3rdparty/phonon/mmf/videooutput.cpp
+++ b/src/3rdparty/phonon/mmf/videooutput.cpp
@@ -16,6 +16,7 @@ along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "ancestormovemonitor.h"
#include "utils.h"
#include "videooutput.h"
#include "videooutputobserver.h"
@@ -44,8 +45,10 @@ using namespace Phonon::MMF;
// Constructor / destructor
//-----------------------------------------------------------------------------
-MMF::VideoOutput::VideoOutput(QWidget* parent)
+MMF::VideoOutput::VideoOutput
+ (AncestorMoveMonitor* ancestorMoveMonitor, QWidget* parent)
: QWidget(parent)
+ , m_ancestorMoveMonitor(ancestorMoveMonitor)
, m_observer(0)
{
TRACE_CONTEXT(VideoOutput::VideoOutput, EVideoInternal);
@@ -63,6 +66,8 @@ MMF::VideoOutput::VideoOutput(QWidget* parent)
// to be invisible when running on the target device.
qt_widget_private(this)->extraData()->disableBlit = true;
+ registerForAncestorMoved();
+
dump();
TRACE_EXIT_0();
@@ -73,6 +78,8 @@ MMF::VideoOutput::~VideoOutput()
TRACE_CONTEXT(VideoOutput::~VideoOutput, EVideoInternal);
TRACE_ENTRY_0();
+ m_ancestorMoveMonitor->unRegisterTarget(this);
+
TRACE_EXIT_0();
}
@@ -97,6 +104,15 @@ void MMF::VideoOutput::setObserver(VideoOutputObserver* observer)
m_observer = observer;
}
+void MMF::VideoOutput::ancestorMoved()
+{
+ TRACE_CONTEXT(VideoOutput::ancestorMoved, EVideoInternal);
+ TRACE_ENTRY_0();
+
+ videoOutputRegionChanged();
+
+ TRACE_EXIT_0();
+}
//-----------------------------------------------------------------------------
// QWidget
@@ -154,8 +170,11 @@ bool MMF::VideoOutput::event(QEvent* event)
TRACE_0("WinIdChange");
videoOutputRegionChanged();
return true;
- }
- else
+ } else if (event->type() == QEvent::ParentChange) {
+ // Tell ancestor move monitor to update ancestor list for this widget
+ registerForAncestorMoved();
+ return true;
+ } else
return QWidget::event(event);
}
@@ -171,6 +190,11 @@ void MMF::VideoOutput::videoOutputRegionChanged()
m_observer->videoOutputRegionChanged();
}
+void MMF::VideoOutput::registerForAncestorMoved()
+{
+ m_ancestorMoveMonitor->registerTarget(this);
+}
+
void MMF::VideoOutput::dump() const
{
#ifndef QT_NO_DEBUG
diff --git a/src/3rdparty/phonon/mmf/videooutput.h b/src/3rdparty/phonon/mmf/videooutput.h
index 7bc0b52..db4d127 100644
--- a/src/3rdparty/phonon/mmf/videooutput.h
+++ b/src/3rdparty/phonon/mmf/videooutput.h
@@ -30,6 +30,7 @@ namespace Phonon
{
namespace MMF
{
+class AncestorMoveMonitor;
class VideoOutputObserver;
class VideoOutput : public QWidget
@@ -37,12 +38,14 @@ class VideoOutput : public QWidget
Q_OBJECT
public:
- explicit VideoOutput(QWidget* parent);
+ VideoOutput(AncestorMoveMonitor* ancestorMoveMonitor, QWidget* parent);
~VideoOutput();
void setFrameSize(const QSize& size);
void setObserver(VideoOutputObserver* observer);
+ void ancestorMoved();
+
protected:
// Override QWidget functions
QSize sizeHint() const;
@@ -55,11 +58,17 @@ private:
void dump() const;
void videoOutputRegionChanged();
+ void registerForAncestorMoved();
+
private:
- QSize m_frameSize;
+ // Not owned
+ AncestorMoveMonitor* m_ancestorMoveMonitor;
// Not owned
- VideoOutputObserver* m_observer;
+ VideoOutputObserver* m_observer;
+
+ QSize m_frameSize;
+
};
}
}
diff --git a/src/3rdparty/phonon/mmf/videowidget.cpp b/src/3rdparty/phonon/mmf/videowidget.cpp
index 8a5c9ff..7d7abf1 100644
--- a/src/3rdparty/phonon/mmf/videowidget.cpp
+++ b/src/3rdparty/phonon/mmf/videowidget.cpp
@@ -49,9 +49,10 @@ static const qreal DefaultSaturation = 1.0;
// Constructor / destructor
//-----------------------------------------------------------------------------
-MMF::VideoWidget::VideoWidget(QWidget* parent)
+MMF::VideoWidget::VideoWidget
+ (AncestorMoveMonitor* ancestorMoveMonitor, QWidget* parent)
: MediaNode(parent)
- , m_widget(new VideoOutput(parent))
+ , m_widget(new VideoOutput(ancestorMoveMonitor, parent))
, m_aspectRatio(DefaultAspectRatio)
, m_brightness(DefaultBrightness)
, m_scaleMode(DefaultScaleMode)
diff --git a/src/3rdparty/phonon/mmf/videowidget.h b/src/3rdparty/phonon/mmf/videowidget.h
index 970f749..318dfae 100644
--- a/src/3rdparty/phonon/mmf/videowidget.h
+++ b/src/3rdparty/phonon/mmf/videowidget.h
@@ -31,6 +31,7 @@ namespace Phonon
{
namespace MMF
{
+class AncestorMoveMonitor;
class VideoOutput;
class VideoWidget : public MediaNode
@@ -40,7 +41,7 @@ class VideoWidget : public MediaNode
Q_INTERFACES(Phonon::VideoWidgetInterface)
public:
- VideoWidget(QWidget* parent);
+ VideoWidget(AncestorMoveMonitor* ancestorMoveMonitor, QWidget* parent);
~VideoWidget();
// VideoWidgetInterface