diff options
Diffstat (limited to 'src/3rdparty/phonon/mmf')
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 |