summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/phonon/mmf
diff options
context:
space:
mode:
authorQt by Nokia <qt-info@nokia.com>2011-04-27 12:05:43 +0200
committeraxis <qt-info@nokia.com>2011-04-27 12:05:43 +0200
commit356978ecce23e076e1b622d5d41dd8c04bf7bcf8 (patch)
tree8e1874cc32750e30b84b2561387d48424e076ae3 /src/3rdparty/phonon/mmf
Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12
Diffstat (limited to 'src/3rdparty/phonon/mmf')
-rw-r--r--src/3rdparty/phonon/mmf/abstractaudioeffect.cpp195
-rw-r--r--src/3rdparty/phonon/mmf/abstractaudioeffect.h142
-rw-r--r--src/3rdparty/phonon/mmf/abstractmediaplayer.cpp707
-rw-r--r--src/3rdparty/phonon/mmf/abstractmediaplayer.h161
-rw-r--r--src/3rdparty/phonon/mmf/abstractplayer.cpp199
-rw-r--r--src/3rdparty/phonon/mmf/abstractplayer.h176
-rw-r--r--src/3rdparty/phonon/mmf/abstractvideooutput.cpp172
-rw-r--r--src/3rdparty/phonon/mmf/abstractvideooutput.h93
-rw-r--r--src/3rdparty/phonon/mmf/abstractvideoplayer.cpp518
-rw-r--r--src/3rdparty/phonon/mmf/abstractvideoplayer.h173
-rw-r--r--src/3rdparty/phonon/mmf/ancestormovemonitor.cpp179
-rw-r--r--src/3rdparty/phonon/mmf/ancestormovemonitor.h95
-rw-r--r--src/3rdparty/phonon/mmf/audioequalizer.cpp106
-rw-r--r--src/3rdparty/phonon/mmf/audioequalizer.h67
-rw-r--r--src/3rdparty/phonon/mmf/audiooutput.cpp114
-rw-r--r--src/3rdparty/phonon/mmf/audiooutput.h94
-rw-r--r--src/3rdparty/phonon/mmf/audioplayer.cpp293
-rw-r--r--src/3rdparty/phonon/mmf/audioplayer.h124
-rw-r--r--src/3rdparty/phonon/mmf/backend.cpp223
-rw-r--r--src/3rdparty/phonon/mmf/backend.h70
-rw-r--r--src/3rdparty/phonon/mmf/bassboost.cpp59
-rw-r--r--src/3rdparty/phonon/mmf/bassboost.h60
-rw-r--r--src/3rdparty/phonon/mmf/defs.h52
-rw-r--r--src/3rdparty/phonon/mmf/download.cpp199
-rw-r--r--src/3rdparty/phonon/mmf/download.h109
-rw-r--r--src/3rdparty/phonon/mmf/dummyplayer.cpp115
-rw-r--r--src/3rdparty/phonon/mmf/dummyplayer.h69
-rw-r--r--src/3rdparty/phonon/mmf/effectfactory.cpp215
-rw-r--r--src/3rdparty/phonon/mmf/effectfactory.h101
-rw-r--r--src/3rdparty/phonon/mmf/effectparameter.cpp71
-rw-r--r--src/3rdparty/phonon/mmf/effectparameter.h74
-rw-r--r--src/3rdparty/phonon/mmf/environmentalreverb.cpp212
-rw-r--r--src/3rdparty/phonon/mmf/environmentalreverb.h62
-rw-r--r--src/3rdparty/phonon/mmf/loudness.cpp59
-rw-r--r--src/3rdparty/phonon/mmf/loudness.h60
-rw-r--r--src/3rdparty/phonon/mmf/mediaobject.cpp561
-rw-r--r--src/3rdparty/phonon/mmf/mediaobject.h160
-rw-r--r--src/3rdparty/phonon/mmf/mmf_medianode.cpp152
-rw-r--r--src/3rdparty/phonon/mmf/mmf_medianode.h108
-rw-r--r--src/3rdparty/phonon/mmf/objectdump.cpp525
-rw-r--r--src/3rdparty/phonon/mmf/objectdump.h164
-rw-r--r--src/3rdparty/phonon/mmf/objectdump_symbian.cpp160
-rw-r--r--src/3rdparty/phonon/mmf/objectdump_symbian.h66
-rw-r--r--src/3rdparty/phonon/mmf/objecttree.cpp100
-rw-r--r--src/3rdparty/phonon/mmf/objecttree.h115
-rw-r--r--src/3rdparty/phonon/mmf/stereowidening.cpp93
-rw-r--r--src/3rdparty/phonon/mmf/stereowidening.h62
-rw-r--r--src/3rdparty/phonon/mmf/utils.cpp260
-rw-r--r--src/3rdparty/phonon/mmf/utils.h176
-rw-r--r--src/3rdparty/phonon/mmf/videooutput_dsa.cpp183
-rw-r--r--src/3rdparty/phonon/mmf/videooutput_dsa.h109
-rw-r--r--src/3rdparty/phonon/mmf/videooutput_surface.cpp87
-rw-r--r--src/3rdparty/phonon/mmf/videooutput_surface.h66
-rw-r--r--src/3rdparty/phonon/mmf/videoplayer_dsa.cpp317
-rw-r--r--src/3rdparty/phonon/mmf/videoplayer_dsa.h92
-rw-r--r--src/3rdparty/phonon/mmf/videoplayer_surface.cpp185
-rw-r--r--src/3rdparty/phonon/mmf/videoplayer_surface.h81
-rw-r--r--src/3rdparty/phonon/mmf/videowidget.cpp192
-rw-r--r--src/3rdparty/phonon/mmf/videowidget.h87
59 files changed, 9519 insertions, 0 deletions
diff --git a/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp b/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp
new file mode 100644
index 0000000..9b64ab3
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp
@@ -0,0 +1,195 @@
+/* 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 "mediaobject.h"
+
+#include "abstractaudioeffect.h"
+#include "audioplayer.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+/*! \class MMF::AbstractAudioEffect
+ \internal
+*/
+
+/*! \namespace Phonon::MMF
+ \internal
+*/
+
+AbstractAudioEffect::AbstractAudioEffect(QObject *parent,
+ const QList<EffectParameter> &params)
+ : MediaNode(parent)
+ , m_params(params)
+ , m_player(0)
+{
+
+}
+
+QList<Phonon::EffectParameter> AbstractAudioEffect::parameters() const
+{
+ // Convert from QList<MMF::EffectParameter> to QList<Phonon::EffectParameter>
+ QList<Phonon::EffectParameter> result;
+ EffectParameter param;
+ foreach (param, m_params)
+ result += param;
+ return result;
+}
+
+QVariant AbstractAudioEffect::parameterValue(const Phonon::EffectParameter &queriedParam) const
+{
+ const QVariant &val = m_values.value(queriedParam.id());
+
+ if (val.isNull())
+ return queriedParam.defaultValue();
+ else
+ return val;
+}
+
+void AbstractAudioEffect::setParameterValue(const Phonon::EffectParameter &param,
+ const QVariant &newValue)
+{
+ m_values.insert(param.id(), newValue);
+
+ if (m_effect.data()) {
+ const EffectParameter& internalParam = internalParameter(param.id());
+ int err = parameterChanged(internalParam, newValue);
+ // TODO: handle audio effect errors
+ Q_UNUSED(err);
+ }
+}
+
+void AbstractAudioEffect::abstractPlayerChanged(AbstractPlayer *player)
+{
+ m_player = qobject_cast<AbstractMediaPlayer *>(player);
+ m_effect.reset();
+}
+
+void AbstractAudioEffect::stateChanged(Phonon::State newState,
+ Phonon::State oldState)
+{
+ if (Phonon::LoadingState == oldState
+ && Phonon::LoadingState != newState)
+ createEffect();
+}
+
+void AbstractAudioEffect::connectMediaObject(MediaObject *mediaObject)
+{
+ Q_ASSERT_X(!m_player, Q_FUNC_INFO, "Player already connected");
+ Q_ASSERT_X(!m_effect.data(), Q_FUNC_INFO, "Effect already created");
+
+ abstractPlayerChanged(mediaObject->abstractPlayer());
+
+ connect(mediaObject, SIGNAL(stateChanged(Phonon::State, Phonon::State)),
+ SLOT(stateChanged(Phonon::State, Phonon::State)));
+
+ connect(mediaObject, SIGNAL(abstractPlayerChanged(AbstractPlayer *)),
+ SLOT(abstractPlayerChanged(AbstractPlayer *)));
+
+ if (mediaObject->state() != Phonon::LoadingState)
+ createEffect();
+}
+
+void AbstractAudioEffect::disconnectMediaObject(MediaObject *mediaObject)
+{
+ mediaObject->disconnect(this);
+ abstractPlayerChanged(0);
+}
+
+void AbstractAudioEffect::setEnabled(bool enabled)
+{
+ TInt err = KErrNone;
+
+ if (enabled)
+ // TODO: handle audio effect errors
+ TRAP(err, m_effect->EnableL())
+ else
+ // TODO: handle audio effect errors
+ TRAP(err, m_effect->DisableL())
+
+ Q_UNUSED(err);
+}
+
+void AbstractAudioEffect::createEffect()
+{
+ Q_ASSERT_X(m_player, Q_FUNC_INFO, "Invalid media player pointer");
+
+ if (AudioPlayer *audioPlayer = qobject_cast<AudioPlayer *>(m_player)) {
+ createEffect(audioPlayer->nativePlayer());
+ }
+
+ if (m_effect.data()) {
+ EffectParameter param;
+ int err = 0;
+ foreach (param, m_params) {
+ const QVariant value = parameterValue(param);
+ err = parameterChanged(param, value);
+ }
+ Q_UNUSED(err)
+ }
+}
+
+const MMF::EffectParameter& AbstractAudioEffect::internalParameter(int id) const
+{
+ const EffectParameter *result = 0;
+ for (int i=0; i<m_params.count() && !result; ++i) {
+ if (m_params[i].id() == id)
+ result = &m_params[i];
+ }
+ Q_ASSERT_X(result, Q_FUNC_INFO, "Parameter not found");
+ return *result;
+}
+
+int AbstractAudioEffect::parameterChanged(const EffectParameter &param,
+ const QVariant &value)
+{
+ int err = 0;
+
+ switch (param.id()) {
+ case ParameterEnable:
+ setEnabled(value.toBool());
+ break;
+ default:
+ {
+ const EffectParameter& internalParam = internalParameter(param.id());
+ err = effectParameterChanged(internalParam, value);
+ }
+ break;
+ }
+
+ if (!err)
+ TRAP(err, m_effect->ApplyL());
+
+ return err;
+}
+
+int AbstractAudioEffect::effectParameterChanged(
+ const EffectParameter &param, const QVariant &value)
+{
+ // Default implementation
+ Q_UNUSED(param)
+ Q_UNUSED(value)
+ Q_ASSERT_X(false, Q_FUNC_INFO, "Effect has no parameters");
+ return 0;
+}
+
+
+QT_END_NAMESPACE
+
diff --git a/src/3rdparty/phonon/mmf/abstractaudioeffect.h b/src/3rdparty/phonon/mmf/abstractaudioeffect.h
new file mode 100644
index 0000000..517a334
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/abstractaudioeffect.h
@@ -0,0 +1,142 @@
+/* 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_ABSTRACTEFFECT_H
+#define PHONON_MMF_ABSTRACTEFFECT_H
+
+#include <QScopedPointer>
+
+#include <AudioEffectBase.h>
+
+#include <phonon/effectinterface.h>
+
+#include "audioplayer.h"
+#include "effectparameter.h"
+#include "mmf_medianode.h"
+
+class CMdaAudioOutputStream;
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace MMF
+{
+class AbstractPlayer;
+class AbstractMediaPlayer;
+
+/**
+ * @short Base class for all effects for MMF.
+ *
+ * Adhering to Phonon with MMF is cumbersome because of a number of reasons:
+ *
+ * - MMF has no concept of effect chaining. Simply, an effect is a applied
+ * to PlayerUtility, that's it. This means that the order of effects is
+ * undefined.
+ * - We apply an effect to a PlayerUtility, and MediaObject has that one.
+ * However, effects might be created before MediaObject, but nevertheless
+ * needs to work. We solve this by that we are aware of the whole connection
+ * chain, and whenever a connection happens, we walk the chain, find effects
+ * that aren't applied, and apply it if we have a media object.
+ * - There are plenty of corner cases which we don't handle and where behavior
+ * are undefined. For instance, graphs with more than one MediaObject.
+ */
+class AbstractAudioEffect : public MediaNode
+ , public EffectInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(Phonon::EffectInterface)
+public:
+ AbstractAudioEffect(QObject *parent,
+ const QList<EffectParameter> &params);
+
+ // Phonon::EffectInterface
+ virtual QList<Phonon::EffectParameter> parameters() const;
+ virtual QVariant parameterValue(const Phonon::EffectParameter &param) const;
+ virtual void setParameterValue(const Phonon::EffectParameter &,
+ const QVariant &newValue);
+
+ // Parameters which are shared by all effects
+ enum CommonParameters
+ {
+ ParameterEnable = 0,
+ ParameterBase // must be last entry in enum
+ };
+
+public Q_SLOTS:
+ void abstractPlayerChanged(AbstractPlayer *player);
+ void stateChanged(Phonon::State newState,
+ Phonon::State oldState);
+
+protected:
+ // MediaNode
+ void connectMediaObject(MediaObject *mediaObject);
+ void disconnectMediaObject(MediaObject *mediaObject);
+
+ virtual void createEffect(AudioPlayer::NativePlayer *player) = 0;
+
+ // Effect-specific parameter changed
+ virtual int effectParameterChanged(const EffectParameter &param,
+ const QVariant &value);
+
+private:
+ void createEffect();
+ void setEnabled(bool enabled);
+ const EffectParameter& internalParameter(int id) const;
+ int parameterChanged(const EffectParameter &param,
+ const QVariant &value);
+
+protected:
+ QScopedPointer<CAudioEffect> m_effect;
+
+private:
+ const QList<EffectParameter> m_params;
+ AbstractMediaPlayer * m_player;
+ QHash<int, QVariant> m_values;
+};
+
+}
+}
+
+
+// Macro for defining functions which depend on the native class name
+// for each of the effects. Using this reduces repetition of boilerplate
+// in the implementations of the backend effect nodes.
+
+#ifdef Q_CC_NOKIAX86
+# pragma warn_illtokenpasting off
+#endif
+
+#define PHONON_MMF_DEFINE_EFFECT_FUNCTIONS(Effect) \
+ \
+void Effect::createEffect(AudioPlayer::NativePlayer *player) \
+{ \
+ C##Effect *ptr = 0; \
+ QT_TRAP_THROWING(ptr = C##Effect::NewL(*player)); \
+ m_effect.reset(ptr); \
+} \
+ \
+C##Effect* Effect::concreteEffect() \
+{ \
+ return static_cast<C##Effect *>(m_effect.data()); \
+}
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp
new file mode 100644
index 0000000..4f7caff
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp
@@ -0,0 +1,707 @@
+/* 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 <QResource>
+#include <QUrl>
+
+#include "abstractmediaplayer.h"
+#include "defs.h"
+#include "mediaobject.h"
+#include "utils.h"
+#include <cdbcols.h>
+#include <cdblen.h>
+#include <commdb.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+/*! \class MMF::AbstractMediaPlayer
+ \internal
+*/
+
+//-----------------------------------------------------------------------------
+// Constants
+//-----------------------------------------------------------------------------
+
+const int NullMaxVolume = -1;
+const int BufferStatusTimerInterval = 100; // ms
+
+
+//-----------------------------------------------------------------------------
+// Constructor / destructor
+//-----------------------------------------------------------------------------
+
+MMF::AbstractMediaPlayer::AbstractMediaPlayer
+ (MediaObject *parent, const AbstractPlayer *player)
+ : AbstractPlayer(player)
+ , m_parent(parent)
+ , m_pending(NothingPending)
+ , m_positionTimer(new QTimer(this))
+ , m_position(0)
+ , m_bufferStatusTimer(new QTimer(this))
+ , m_mmfMaxVolume(NullMaxVolume)
+ , m_prefinishMarkSent(false)
+ , m_aboutToFinishSent(false)
+#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
+ , m_download(0)
+ , m_downloadStalled(false)
+#endif
+{
+ connect(m_positionTimer.data(), SIGNAL(timeout()), this, SLOT(positionTick()));
+ connect(m_bufferStatusTimer.data(), SIGNAL(timeout()), this, SLOT(bufferStatusTick()));
+}
+
+//-----------------------------------------------------------------------------
+// MediaObjectInterface
+//-----------------------------------------------------------------------------
+
+void MMF::AbstractMediaPlayer::play()
+{
+ TRACE_CONTEXT(AbstractMediaPlayer::play, EAudioApi);
+ TRACE_ENTRY("state %d", privateState());
+
+ switch (privateState()) {
+ case GroundState:
+ setError(tr("Not ready to play"));
+ break;
+
+ case LoadingState:
+ setPending(PlayPending);
+ break;
+
+ case StoppedState:
+ case PausedState:
+ startPlayback();
+ break;
+
+ case PlayingState:
+ case BufferingState:
+ case ErrorState:
+ // Do nothing
+ break;
+
+ // Protection against adding new states and forgetting to update this switch
+ default:
+ TRACE_PANIC(InvalidStatePanic);
+ }
+
+ TRACE_EXIT("state %d", privateState());
+}
+
+void MMF::AbstractMediaPlayer::pause()
+{
+ TRACE_CONTEXT(AbstractMediaPlayer::pause, EAudioApi);
+ TRACE_ENTRY("state %d", privateState());
+
+ stopTimers();
+
+ switch (privateState()) {
+ case GroundState:
+ case LoadingState:
+ case StoppedState:
+ setPending(PausePending);
+ break;
+
+ case PausedState:
+ // Do nothing
+ break;
+
+ case PlayingState:
+ case BufferingState:
+ changeState(PausedState);
+ // Fall through
+ case ErrorState:
+ doPause();
+ break;
+
+ // Protection against adding new states and forgetting to update this switch
+ default:
+ TRACE_PANIC(InvalidStatePanic);
+ }
+
+ TRACE_EXIT("state %d", privateState());
+}
+
+void MMF::AbstractMediaPlayer::stop()
+{
+ TRACE_CONTEXT(AbstractMediaPlayer::stop, EAudioApi);
+ TRACE_ENTRY("state %d", privateState());
+
+ setPending(NothingPending);
+ stopTimers();
+
+ switch (privateState()) {
+ case GroundState:
+ case LoadingState:
+ case StoppedState:
+ case ErrorState:
+ // Do nothing
+ break;
+
+ case PlayingState:
+ case BufferingState:
+ case PausedState:
+ doStop();
+ changeState(StoppedState);
+ break;
+
+ // Protection against adding new states and forgetting to update this switch
+ default:
+ TRACE_PANIC(InvalidStatePanic);
+ }
+
+ TRACE_EXIT("state %d", privateState());
+}
+
+void MMF::AbstractMediaPlayer::seek(qint64 ms)
+{
+ TRACE_CONTEXT(AbstractMediaPlayer::seek, EAudioApi);
+ TRACE_ENTRY("state %d pos %Ld", state(), ms);
+
+ switch (privateState()) {
+ // Fallthrough all these
+ case GroundState:
+ case StoppedState:
+ case PausedState:
+ case PlayingState:
+ case LoadingState:
+ {
+ bool wasPlaying = false;
+ if (state() == PlayingState) {
+ stopPositionTimer();
+ doPause();
+ wasPlaying = true;
+ }
+
+ doSeek(ms);
+ m_position = ms;
+ resetMarksIfRewound();
+
+ if(wasPlaying && state() != ErrorState) {
+ doPlay();
+ startPositionTimer();
+ }
+
+ break;
+ }
+ case BufferingState:
+ // Fallthrough
+ case ErrorState:
+ // Do nothing
+ break;
+ }
+
+ TRACE_EXIT_0();
+}
+
+bool MMF::AbstractMediaPlayer::isSeekable() const
+{
+ return true;
+}
+
+qint64 MMF::AbstractMediaPlayer::currentTime() const
+{
+ return m_position;
+}
+
+void MMF::AbstractMediaPlayer::doSetTickInterval(qint32 interval)
+{
+ TRACE_CONTEXT(AbstractMediaPlayer::doSetTickInterval, EAudioApi);
+ TRACE_ENTRY("state %d m_interval %d interval %d", privateState(), tickInterval(), interval);
+
+ m_positionTimer->setInterval(interval);
+
+ TRACE_EXIT_0();
+}
+
+void MMF::AbstractMediaPlayer::open()
+{
+ TRACE_CONTEXT(AbstractMediaPlayer::open, EAudioApi);
+ const MediaSource source = m_parent->source();
+ TRACE_ENTRY("state %d source.type %d", privateState(), source.type());
+
+ close();
+ changeState(GroundState);
+
+ TInt symbianErr = KErrNone;
+ QString errorMessage;
+
+ switch (source.type()) {
+ case MediaSource::LocalFile: {
+ RFile *const file = m_parent->file();
+ Q_ASSERT(file);
+ symbianErr = openFile(*file);
+ if (KErrNone != symbianErr)
+ errorMessage = tr("Error opening file");
+ break;
+ }
+
+ case MediaSource::Url: {
+ const QUrl url(source.url());
+ if (url.scheme() == QLatin1String("file")) {
+ RFile *const file = m_parent->file();
+ Q_ASSERT(file);
+ symbianErr = openFile(*file);
+ if (KErrNone != symbianErr)
+ errorMessage = tr("Error opening file");
+ }
+#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
+ else if (url.scheme() == QLatin1String("http")) {
+ Q_ASSERT(!m_download);
+ m_download = new Download(url, this);
+ connect(m_download, SIGNAL(lengthChanged(qint64)),
+ this, SLOT(downloadLengthChanged(qint64)));
+ connect(m_download, SIGNAL(stateChanged(Download::State)),
+ this, SLOT(downloadStateChanged(Download::State)));
+ int iap = m_parent->currentIAP();
+ TRACE("HTTP Url: Using IAP %d", iap);
+ m_download->start(iap);
+ }
+#endif
+ else {
+ int iap = m_parent->currentIAP();
+ TRACE("Using IAP %d", iap);
+ symbianErr = openUrl(url.toString(), iap);
+ if (KErrNone != symbianErr)
+ errorMessage = tr("Error opening URL");
+ }
+
+ break;
+ }
+
+ case MediaSource::Stream: {
+ QResource *const resource = m_parent->resource();
+ if (resource) {
+ m_buffer.Set(resource->data(), resource->size());
+ symbianErr = openDescriptor(m_buffer);
+ if (KErrNone != symbianErr)
+ errorMessage = tr("Error opening resource");
+ } else {
+ errorMessage = tr("Error opening source: resource not opened");
+ }
+ break;
+ }
+
+ // Other source types are handled in MediaObject::createPlayer
+
+ // Protection against adding new media types and forgetting to update this switch
+ default:
+ TRACE_PANIC(InvalidMediaTypePanic);
+ }
+
+ if (errorMessage.isEmpty()) {
+ changeState(LoadingState);
+ } else {
+ if (symbianErr)
+ setError(errorMessage, symbianErr);
+ else
+ setError(errorMessage);
+ }
+
+ TRACE_EXIT_0();
+}
+
+void MMF::AbstractMediaPlayer::close()
+{
+ doClose();
+#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
+ delete m_download;
+ m_download = 0;
+#endif
+ m_position = 0;
+}
+
+void MMF::AbstractMediaPlayer::volumeChanged(qreal volume)
+{
+ TRACE_CONTEXT(AbstractMediaPlayer::volumeChanged, EAudioInternal);
+ TRACE_ENTRY("state %d", privateState());
+
+ AbstractPlayer::volumeChanged(volume);
+ doVolumeChanged();
+
+ TRACE_EXIT_0();
+}
+
+//-----------------------------------------------------------------------------
+// Private functions
+//-----------------------------------------------------------------------------
+
+void MMF::AbstractMediaPlayer::startPositionTimer()
+{
+ m_positionTimer->start(tickInterval());
+}
+
+void MMF::AbstractMediaPlayer::stopPositionTimer()
+{
+ m_positionTimer->stop();
+}
+
+void MMF::AbstractMediaPlayer::startBufferStatusTimer()
+{
+ m_bufferStatusTimer->start(BufferStatusTimerInterval);
+}
+
+void MMF::AbstractMediaPlayer::stopBufferStatusTimer()
+{
+ m_bufferStatusTimer->stop();
+}
+
+void MMF::AbstractMediaPlayer::stopTimers()
+{
+ stopPositionTimer();
+ stopBufferStatusTimer();
+}
+
+void MMF::AbstractMediaPlayer::doVolumeChanged()
+{
+ switch (privateState()) {
+ case GroundState:
+ case LoadingState:
+ case ErrorState:
+ // Do nothing
+ break;
+
+ case StoppedState:
+ case PausedState:
+ case PlayingState:
+ case BufferingState: {
+ const qreal volume = (m_volume * m_mmfMaxVolume) + 0.5;
+ const int err = setDeviceVolume(volume);
+
+ if (KErrNone != err) {
+ setError(tr("Setting volume failed"), err);
+ }
+ break;
+ }
+
+ // Protection against adding new states and forgetting to update this
+ // switch
+ default:
+ Utils::panic(InvalidStatePanic);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Protected functions
+//-----------------------------------------------------------------------------
+
+void MMF::AbstractMediaPlayer::bufferingStarted()
+{
+ m_stateBeforeBuffering = privateState();
+ changeState(BufferingState);
+ bufferStatusTick();
+ startBufferStatusTimer();
+}
+
+void MMF::AbstractMediaPlayer::bufferingComplete()
+{
+ stopBufferStatusTimer();
+ emit MMF::AbstractPlayer::bufferStatus(100);
+ if (!progressiveDownloadStalled())
+ changeState(m_stateBeforeBuffering);
+}
+
+void MMF::AbstractMediaPlayer::maxVolumeChanged(int mmfMaxVolume)
+{
+ m_mmfMaxVolume = mmfMaxVolume;
+ doVolumeChanged();
+}
+
+void MMF::AbstractMediaPlayer::loadingComplete(int error)
+{
+ TRACE_CONTEXT(AbstractMediaPlayer::loadingComplete, EAudioApi);
+ TRACE_ENTRY("state %d error %d", state(), error);
+ if (progressiveDownloadStalled()) {
+ Q_ASSERT(Phonon::BufferingState == state());
+ if (KErrNone == error) {
+ bufferingComplete();
+ doSeek(m_position);
+ startPlayback();
+#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
+ m_downloadStalled = false;
+#endif
+ }
+ } else {
+ Q_ASSERT(Phonon::LoadingState == state());
+ if (KErrNone == error) {
+ updateMetaData();
+ changeState(StoppedState);
+ } else {
+ if (isProgressiveDownload() && KErrCorrupt == error) {
+ setProgressiveDownloadStalled();
+ } else {
+ setError(tr("Loading clip failed"), error);
+ }
+ }
+ }
+}
+
+void MMF::AbstractMediaPlayer::playbackComplete(int error)
+{
+ stopTimers();
+
+ if (KErrNone == error && !m_aboutToFinishSent) {
+ const qint64 total = totalTime();
+ emit MMF::AbstractPlayer::tick(total);
+ m_aboutToFinishSent = true;
+ emit aboutToFinish();
+ }
+
+ if (KErrNone == error) {
+ changeState(PausedState);
+
+ // MediaObject::switchToNextSource deletes the current player, so we
+ // call it via delayed slot invokation to ensure that this object does
+ // not get deleted during execution of a member function.
+ QMetaObject::invokeMethod(m_parent, "switchToNextSource", Qt::QueuedConnection);
+ }
+ else {
+ if (isProgressiveDownload() && KErrCorrupt == error) {
+ setProgressiveDownloadStalled();
+ } else {
+ setError(tr("Playback complete"), error);
+ emit finished();
+ }
+ }
+}
+
+qint64 MMF::AbstractMediaPlayer::toMilliSeconds(const TTimeIntervalMicroSeconds &in)
+{
+ return in.Int64() / 1000;
+}
+
+bool MMF::AbstractMediaPlayer::isProgressiveDownload() const
+{
+#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
+ return (0 != m_download);
+#else
+ return false;
+#endif
+}
+
+bool MMF::AbstractMediaPlayer::progressiveDownloadStalled() const
+{
+#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
+ return m_downloadStalled;
+#else
+ return false;
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Slots
+//-----------------------------------------------------------------------------
+
+void MMF::AbstractMediaPlayer::positionTick()
+{
+ const qint64 pos = getCurrentTime();
+ if (pos > m_position) {
+ m_position = pos;
+ emitMarksIfReached(m_position);
+ emit MMF::AbstractPlayer::tick(m_position);
+ }
+}
+
+void MMF::AbstractMediaPlayer::emitMarksIfReached(qint64 current)
+{
+ const qint64 total = totalTime();
+ const qint64 remaining = total - current;
+
+ if (prefinishMark() && !m_prefinishMarkSent) {
+ if (remaining < (prefinishMark() + tickInterval()/2)) {
+ m_prefinishMarkSent = true;
+ emit prefinishMarkReached(remaining);
+ }
+ }
+
+ if (!m_aboutToFinishSent) {
+ if (remaining < tickInterval()) {
+ m_aboutToFinishSent = true;
+ emit aboutToFinish();
+ }
+ }
+}
+
+void MMF::AbstractMediaPlayer::resetMarksIfRewound()
+{
+ const qint64 current = getCurrentTime();
+ const qint64 total = totalTime();
+ const qint64 remaining = total - current;
+
+ if (prefinishMark() && m_prefinishMarkSent)
+ if (remaining >= (prefinishMark() + tickInterval()/2))
+ m_prefinishMarkSent = false;
+
+ if (m_aboutToFinishSent)
+ if (remaining >= tickInterval())
+ m_aboutToFinishSent = false;
+}
+
+void MMF::AbstractMediaPlayer::setPending(Pending pending)
+{
+ const Phonon::State oldState = state();
+ m_pending = pending;
+ const Phonon::State newState = state();
+ if (newState != oldState)
+ emit stateChanged(newState, oldState);
+}
+
+void MMF::AbstractMediaPlayer::startPlayback()
+{
+ doPlay();
+ startPositionTimer();
+ changeState(PlayingState);
+}
+
+void MMF::AbstractMediaPlayer::setProgressiveDownloadStalled()
+{
+#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
+ TRACE_CONTEXT(AbstractMediaPlayer::setProgressiveDownloadStalled, EAudioApi);
+ TRACE_ENTRY("state %d", state());
+ Q_ASSERT(isProgressiveDownload());
+ m_downloadStalled = true;
+ doClose();
+ bufferingStarted();
+ // Video player loses window handle when closed - need to reapply it here
+ videoOutputChanged();
+ m_download->resume();
+#endif
+}
+
+void MMF::AbstractMediaPlayer::bufferStatusTick()
+{
+ // During progressive download, there is no way to detect the buffering status.
+ // Phonon does not support a "buffering; amount unknown" signal, therefore we
+ // return a buffering status of zero.
+ const int status = progressiveDownloadStalled() ? 0 : bufferStatus();
+ emit MMF::AbstractPlayer::bufferStatus(status);
+}
+
+#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
+void MMF::AbstractMediaPlayer::downloadLengthChanged(qint64 length)
+{
+ TRACE_CONTEXT(AbstractMediaPlayer::downloadLengthChanged, EAudioApi);
+ TRACE_ENTRY("length %Ld", length);
+ Q_UNUSED(length)
+ if (m_downloadStalled) {
+ bufferingComplete();
+ int err = m_parent->openFileHandle(m_download->targetFileName());
+ if (KErrNone == err)
+ err = openFile(*m_parent->file());
+ if (KErrNone != err)
+ setError(tr("Error opening file"));
+ }
+}
+
+void MMF::AbstractMediaPlayer::downloadStateChanged(Download::State state)
+{
+ TRACE_CONTEXT(AbstractMediaPlayer::downloadStateChanged, EAudioApi);
+ TRACE_ENTRY("state %d", state);
+ switch (state) {
+ case Download::Idle:
+ case Download::Initializing:
+ break;
+ case Download::Downloading:
+ {
+ int err = m_parent->openFileHandle(m_download->targetFileName());
+ if (KErrNone == err)
+ err = openFile(*m_parent->file());
+ else if (KErrCorrupt == err)
+ // Insufficient data downloaded - enter Buffering state
+ setProgressiveDownloadStalled();
+ if (KErrNone != err)
+ setError(tr("Error opening file"));
+ }
+ break;
+ case Download::Complete:
+ break;
+ case Download::Error:
+ setError(tr("Download error"));
+ break;
+ }
+}
+#endif // PHONON_MMF_PROGRESSIVE_DOWNLOAD
+
+Phonon::State MMF::AbstractMediaPlayer::phononState(PrivateState state) const
+{
+ Phonon::State result = AbstractPlayer::phononState(state);
+
+ if (PausePending == m_pending) {
+ Q_ASSERT(Phonon::StoppedState == result || Phonon::LoadingState == result);
+ result = Phonon::PausedState;
+ }
+
+ return result;
+}
+
+void MMF::AbstractMediaPlayer::changeState(PrivateState newState)
+{
+ TRACE_CONTEXT(AbstractMediaPlayer::changeState, EAudioInternal);
+
+ const Phonon::State oldPhononState = phononState(privateState());
+ const Phonon::State newPhononState = phononState(newState);
+
+ if (LoadingState == oldPhononState && StoppedState == newPhononState) {
+ switch (m_pending) {
+ case NothingPending:
+ AbstractPlayer::changeState(newState);
+ break;
+
+ case PlayPending:
+ changeState(PlayingState); // necessary in order to apply initial volume
+ doVolumeChanged();
+ startPlayback();
+ break;
+
+ case PausePending:
+ AbstractPlayer::changeState(PausedState);
+ break;
+ }
+
+ setPending(NothingPending);
+ } else {
+ AbstractPlayer::changeState(newState);
+ }
+}
+
+void MMF::AbstractMediaPlayer::updateMetaData()
+{
+ 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
new file mode 100644
index 0000000..df0a42f
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.h
@@ -0,0 +1,161 @@
+/* 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_ABSTRACTMEDIAPLAYER_H
+#define PHONON_MMF_ABSTRACTMEDIAPLAYER_H
+
+#include <QTimer>
+#include <QScopedPointer>
+#include <e32std.h>
+#include "abstractplayer.h"
+#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
+# include "download.h"
+#endif
+
+class RFile;
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace MMF
+{
+class AudioOutput;
+class MediaObject;
+
+/**
+ * Interface via which MMF client APIs for both audio and video can be
+ * accessed.
+ */
+class AbstractMediaPlayer : public AbstractPlayer
+{
+ Q_OBJECT
+
+protected:
+ AbstractMediaPlayer(MediaObject *parent, const AbstractPlayer *player);
+
+public:
+ virtual void open();
+ virtual void close();
+
+ // MediaObjectInterface
+ virtual void play();
+ virtual void pause();
+ virtual void stop();
+ virtual void seek(qint64 milliseconds);
+ virtual bool isSeekable() const;
+ virtual qint64 currentTime() const;
+ virtual void volumeChanged(qreal volume);
+
+protected:
+ // AbstractPlayer
+ virtual void doSetTickInterval(qint32 interval);
+ virtual Phonon::State phononState(PrivateState state) const;
+ virtual void changeState(PrivateState newState);
+
+ virtual void doPlay() = 0;
+ virtual void doPause() = 0;
+ virtual void doStop() = 0;
+ virtual void doSeek(qint64 pos) = 0;
+ virtual int setDeviceVolume(int mmfVolume) = 0;
+ virtual int openFile(const QString &fileName) = 0;
+ virtual int openFile(RFile& file) = 0;
+ virtual int openUrl(const QString& url, int iap) = 0;
+ virtual int openDescriptor(const TDesC8 &des) = 0;
+ virtual int bufferStatus() const = 0;
+ virtual void doClose() = 0;
+
+ void updateMetaData();
+ virtual qint64 getCurrentTime() const = 0;
+ virtual int numberOfMetaDataEntries() const = 0;
+ virtual QPair<QString, QString> metaDataEntry(int index) const = 0;
+
+protected:
+ void bufferingStarted();
+ void bufferingComplete();
+ void maxVolumeChanged(int maxVolume);
+ void loadingComplete(int error);
+ void playbackComplete(int error);
+
+ static qint64 toMilliSeconds(const TTimeIntervalMicroSeconds &);
+
+ bool isProgressiveDownload() const;
+ bool progressiveDownloadStalled() const;
+
+private:
+ void startPositionTimer();
+ void stopPositionTimer();
+ void startBufferStatusTimer();
+ void stopBufferStatusTimer();
+ void stopTimers();
+ void doVolumeChanged();
+ void emitMarksIfReached(qint64 position);
+ void resetMarksIfRewound();
+ void startPlayback();
+ void setProgressiveDownloadStalled();
+
+ enum Pending {
+ NothingPending,
+ PausePending,
+ PlayPending
+ };
+
+ void setPending(Pending pending);
+
+private Q_SLOTS:
+ void positionTick();
+ void bufferStatusTick();
+#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
+ void downloadLengthChanged(qint64);
+ void downloadStateChanged(Download::State);
+#endif
+
+private:
+ MediaObject *const m_parent;
+
+ Pending m_pending;
+
+ QScopedPointer<QTimer> m_positionTimer;
+ qint64 m_position;
+
+ QScopedPointer<QTimer> m_bufferStatusTimer;
+ PrivateState m_stateBeforeBuffering;
+
+ int m_mmfMaxVolume;
+
+ bool m_prefinishMarkSent;
+ bool m_aboutToFinishSent;
+
+ // Used for playback of resource files
+ TPtrC8 m_buffer;
+
+#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
+ Download *m_download;
+ bool m_downloadStalled;
+#endif
+
+ QMultiMap<QString, QString> m_metaData;
+
+};
+}
+}
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/3rdparty/phonon/mmf/abstractplayer.cpp b/src/3rdparty/phonon/mmf/abstractplayer.cpp
new file mode 100644
index 0000000..77d7ae0
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/abstractplayer.cpp
@@ -0,0 +1,199 @@
+/* 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 "abstractplayer.h"
+#include "defs.h"
+#include "utils.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+/*! \class MMF::AbstractPlayer
+ \internal
+*/
+
+//-----------------------------------------------------------------------------
+// Constructor / destructor
+//-----------------------------------------------------------------------------
+
+MMF::AbstractPlayer::AbstractPlayer(const AbstractPlayer *player)
+ : m_videoOutput(0)
+ , m_volume(InitialVolume)
+ , m_state(GroundState)
+ , m_error(NoError)
+ , m_tickInterval(DefaultTickInterval)
+ , m_transitionTime(0)
+ , m_prefinishMark(0)
+{
+ if(player) {
+ m_videoOutput = player->m_videoOutput;
+ m_volume = player->m_volume;
+ m_tickInterval = player->m_tickInterval;
+ m_transitionTime = player->m_transitionTime;
+ m_prefinishMark = player->m_prefinishMark;
+
+ // This is to prevent unwanted state transitions occurring as a result
+ // of MediaObject::switchToNextSource() during playlist playback.
+ if (StoppedState == player->m_state)
+ m_state = player->m_state;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// MediaObjectInterface
+//-----------------------------------------------------------------------------
+
+qint32 MMF::AbstractPlayer::tickInterval() const
+{
+ return m_tickInterval;
+}
+
+void MMF::AbstractPlayer::setTickInterval(qint32 interval)
+{
+ m_tickInterval = interval;
+ doSetTickInterval(interval);
+}
+
+qint32 MMF::AbstractPlayer::prefinishMark() const
+{
+ return m_prefinishMark;
+}
+
+void MMF::AbstractPlayer::setPrefinishMark(qint32 mark)
+{
+ m_prefinishMark = mark;
+}
+
+qint32 MMF::AbstractPlayer::transitionTime() const
+{
+ return m_transitionTime;
+}
+
+void MMF::AbstractPlayer::setTransitionTime(qint32 time)
+{
+ m_transitionTime = time;
+}
+
+void MMF::AbstractPlayer::volumeChanged(qreal volume)
+{
+ m_volume = volume;
+}
+
+
+//-----------------------------------------------------------------------------
+// Video output
+//-----------------------------------------------------------------------------
+
+void MMF::AbstractPlayer::setVideoOutput(AbstractVideoOutput* videoOutput)
+{
+ m_videoOutput = videoOutput;
+ videoOutputChanged();
+}
+
+void MMF::AbstractPlayer::videoOutputChanged()
+{
+ // Default behaviour is empty - overridden by VideoPlayer
+}
+
+void MMF::AbstractPlayer::setError(const QString &errorMessage)
+{
+ TRACE_CONTEXT(AbstractPlayer::setError, EAudioInternal);
+ TRACE_ENTRY("state %d", m_state);
+
+ m_error = Phonon::NormalError;
+ m_errorString = errorMessage;
+ changeState(ErrorState);
+
+ TRACE_EXIT_0();
+}
+
+void MMF::AbstractPlayer::setError(const QString &errorMessage, int symbianError)
+{
+ setError(errorMessage + ": " + Utils::symbianErrorToString(symbianError));
+}
+
+Phonon::ErrorType MMF::AbstractPlayer::errorType() const
+{
+ const Phonon::ErrorType result = (ErrorState == m_state)
+ ? m_error : NoError;
+ return result;
+}
+
+QString MMF::AbstractPlayer::errorString() const
+{
+ return m_errorString;
+}
+
+Phonon::State MMF::AbstractPlayer::phononState() const
+{
+ return phononState(m_state);
+}
+
+Phonon::State MMF::AbstractPlayer::phononState(PrivateState state) const
+{
+ 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;
+}
+
+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
new file mode 100644
index 0000000..dd98c7c
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/abstractplayer.h
@@ -0,0 +1,176 @@
+/* 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_ABSTRACTPLAYER_H
+#define PHONON_MMF_ABSTRACTPLAYER_H
+
+#include <phonon/phononnamespace.h>
+#include <phonon/mediasource.h>
+
+#include <QObject>
+
+#include "abstractvideooutput.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace MMF
+{
+
+/**
+ * @short Interface which abstracts from MediaObject the current
+ * media type
+ *
+ * This may be:
+ * - Nothing, in which case this interface is implemented by
+ * DummyPlayer
+ * - Audio, in which case the implementation is AudioPlayer
+ * - Video, in which case the implementation is VideoPlayer
+ */
+class AbstractPlayer : public QObject
+{
+ // Required although this class has no signals or slots
+ // Without this, qobject_cast will fail
+ Q_OBJECT
+
+public:
+ AbstractPlayer(const AbstractPlayer *player);
+
+ virtual void open() = 0;
+ virtual void close() = 0;
+
+ // MediaObjectInterface (implemented)
+ qint32 tickInterval() const;
+ void setTickInterval(qint32);
+ void setTransitionTime(qint32);
+ qint32 transitionTime() const;
+ void setPrefinishMark(qint32);
+ qint32 prefinishMark() const;
+
+ // MediaObjectInterface (abstract)
+ virtual void play() = 0;
+ virtual void pause() = 0;
+ virtual void stop() = 0;
+ virtual void seek(qint64 milliseconds) = 0;
+ virtual bool hasVideo() const = 0;
+ virtual bool isSeekable() const = 0;
+ virtual qint64 currentTime() const = 0;
+ virtual Phonon::ErrorType errorType() const;
+ virtual QString errorString() const;
+ virtual qint64 totalTime() const = 0;
+
+ virtual void volumeChanged(qreal volume);
+
+ void setVideoOutput(AbstractVideoOutput *videoOutput);
+
+ /**
+ * Records error message and changes state to ErrorState
+ */
+ void setError(const QString &errorMessage);
+
+ /**
+ * Records error message and changes state to ErrorState
+ *
+ * Appends a human-readable version of symbianErrorCode to the error message,
+ * e.g.
+ * @code
+ * setError("Opening file failed", KErrPermissionDenied)
+ * @endcode
+ * results in the following error message:
+ * "Opening file failed: permission denied"
+ */
+ void setError(const QString &errorMessage, int symbianErrorCode);
+
+ Phonon::State state() const;
+
+Q_SIGNALS:
+ void totalTimeChanged(qint64 length);
+ void finished();
+ void tick(qint64 time);
+ void bufferStatus(int percentFilled);
+ void stateChanged(Phonon::State newState,
+ Phonon::State oldState);
+ void metaDataChanged(const QMultiMap<QString, QString>& metaData);
+ void aboutToFinish();
+ void prefinishMarkReached(qint32 remaining);
+
+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
+ */
+ virtual Phonon::State phononState(PrivateState state) const;
+
+ virtual void videoOutputChanged();
+
+ PrivateState privateState() const;
+
+ /**
+ * Changes state and emits stateChanged()
+ */
+ virtual void changeState(PrivateState newState);
+
+ /**
+ * 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
+ AbstractVideoOutput* m_videoOutput;
+
+ qreal m_volume;
+
+private:
+ PrivateState m_state;
+ Phonon::ErrorType m_error;
+ QString m_errorString;
+ qint32 m_tickInterval;
+ qint32 m_transitionTime;
+ qint32 m_prefinishMark;
+
+};
+}
+}
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/3rdparty/phonon/mmf/abstractvideooutput.cpp b/src/3rdparty/phonon/mmf/abstractvideooutput.cpp
new file mode 100644
index 0000000..068118b
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/abstractvideooutput.cpp
@@ -0,0 +1,172 @@
+/* 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 "abstractvideooutput.h"
+#include "utils.h"
+
+#ifndef QT_NO_DEBUG
+#include "objectdump.h"
+#endif
+
+#include <QtCore/private/qcore_symbian_p.h> // for qt_TSize2QSize
+
+#include <QMoveEvent>
+#include <QResizeEvent>
+
+#include <QApplication> // for QApplication::activeWindow
+
+#include <coecntrl.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+/*! \class MMF::AbstractVideoOutput
+ \internal
+*/
+
+//-----------------------------------------------------------------------------
+// Constants
+//-----------------------------------------------------------------------------
+
+static const Phonon::VideoWidget::AspectRatio DefaultAspectRatio =
+ Phonon::VideoWidget::AspectRatioAuto;
+static const Phonon::VideoWidget::ScaleMode DefaultScaleMode =
+ Phonon::VideoWidget::FitInView;
+
+
+//-----------------------------------------------------------------------------
+// Constructor / destructor
+//-----------------------------------------------------------------------------
+
+MMF::AbstractVideoOutput::AbstractVideoOutput(QWidget *parent)
+ : QWidget(parent)
+ , m_aspectRatio(DefaultAspectRatio)
+ , m_scaleMode(DefaultScaleMode)
+{
+ // Ensure that this widget has a native window handle
+ winId();
+}
+
+MMF::AbstractVideoOutput::~AbstractVideoOutput()
+{
+
+}
+
+void MMF::AbstractVideoOutput::setVideoSize(const QSize &frameSize)
+{
+ TRACE_CONTEXT(AbstractVideoOutput::setVideoSize, EVideoInternal);
+ TRACE("oldSize %d %d newSize %d %d",
+ m_videoFrameSize.width(), m_videoFrameSize.height(),
+ frameSize.width(), frameSize.height());
+
+ if (frameSize != m_videoFrameSize) {
+ m_videoFrameSize = frameSize;
+ updateGeometry();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// QWidget
+//-----------------------------------------------------------------------------
+
+QSize MMF::AbstractVideoOutput::sizeHint() const
+{
+ // TODO: replace this with a more sensible default
+ QSize result(320, 240);
+
+ if (!m_videoFrameSize.isNull())
+ result = m_videoFrameSize;
+
+ return result;
+}
+
+
+//-----------------------------------------------------------------------------
+// Public functions
+//-----------------------------------------------------------------------------
+
+RWindowBase* MMF::AbstractVideoOutput::videoWindow() const
+{
+ CCoeControl *control = internalWinId();
+ if (!control)
+ control = effectiveWinId();
+
+ RWindowBase *window = 0;
+ if (control)
+ window = control->DrawableWindow();
+
+ return window;
+}
+
+QSize MMF::AbstractVideoOutput::videoWindowSize() const
+{
+ QSize result;
+ if (RWindowBase *const window = videoWindow())
+ result = qt_TSize2QSize(window->Size());
+ return result;
+}
+
+Phonon::VideoWidget::AspectRatio MMF::AbstractVideoOutput::aspectRatio() const
+{
+ return m_aspectRatio;
+}
+
+void MMF::AbstractVideoOutput::setAspectRatio
+ (Phonon::VideoWidget::AspectRatio aspectRatio)
+{
+ if (m_aspectRatio != aspectRatio) {
+ m_aspectRatio = aspectRatio;
+ emit aspectRatioChanged();
+ }
+}
+
+Phonon::VideoWidget::ScaleMode MMF::AbstractVideoOutput::scaleMode() const
+{
+ return m_scaleMode;
+}
+
+void MMF::AbstractVideoOutput::setScaleMode
+ (Phonon::VideoWidget::ScaleMode scaleMode)
+{
+ if (m_scaleMode != scaleMode) {
+ m_scaleMode = scaleMode;
+ emit scaleModeChanged();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Private functions
+//-----------------------------------------------------------------------------
+
+void MMF::AbstractVideoOutput::dump() const
+{
+#ifndef QT_NO_DEBUG
+ TRACE_CONTEXT(AbstractVideoOutput::dump, EVideoInternal);
+ QScopedPointer<ObjectDump::QVisitor> visitor(new ObjectDump::QVisitor);
+ visitor->setPrefix("Phonon::MMF"); // to aid searchability of logs
+ ObjectDump::addDefaultAnnotators(*visitor);
+ ObjectDump::dumpTreeFromLeaf(*this, *visitor);
+#endif
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/3rdparty/phonon/mmf/abstractvideooutput.h b/src/3rdparty/phonon/mmf/abstractvideooutput.h
new file mode 100644
index 0000000..61bcd0f
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/abstractvideooutput.h
@@ -0,0 +1,93 @@
+/* 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_ABSTRACTVIDEOOUTPUT_H
+#define PHONON_MMF_ABSTRACTVIDEOOUTPUT_H
+
+#include <QtGui/QWidget>
+#include <QVector>
+#include <QRect>
+#include "defs.h"
+
+#include <phonon/abstractvideooutput.h>
+#include <phonon/videowidget.h>
+
+#include <e32std.h>
+class RWindowBase;
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace MMF
+{
+
+/**
+ * @short ABC for widget on which video is displayed
+ *
+ * @see DsaVideoOutput, SurfaceVideoOutput
+ */
+class AbstractVideoOutput
+ : public QWidget
+{
+ Q_OBJECT
+
+public:
+ ~AbstractVideoOutput();
+
+ // Set size of video frame. Called by VideoPlayer.
+ void setVideoSize(const QSize &size);
+
+ RWindowBase* videoWindow() const;
+ QSize videoWindowSize() const;
+
+ Phonon::VideoWidget::AspectRatio aspectRatio() const;
+ void setAspectRatio(Phonon::VideoWidget::AspectRatio aspectRatio);
+
+ Phonon::VideoWidget::ScaleMode scaleMode() const;
+ void setScaleMode(Phonon::VideoWidget::ScaleMode scaleMode);
+
+ // Debugging output
+ void dump() const;
+
+Q_SIGNALS:
+ void videoWindowChanged();
+ void aspectRatioChanged();
+ void scaleModeChanged();
+
+protected:
+ AbstractVideoOutput(QWidget *parent);
+
+private:
+ // QWidget
+ QSize sizeHint() const;
+
+private:
+ // Dimensions of the video clip
+ QSize m_videoFrameSize;
+
+ Phonon::VideoWidget::AspectRatio m_aspectRatio;
+ Phonon::VideoWidget::ScaleMode m_scaleMode;
+
+};
+}
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp b/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp
new file mode 100644
index 0000000..ad4ee83
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp
@@ -0,0 +1,518 @@
+/* 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 <QDir>
+#include <QUrl>
+#include <QTimer>
+#include <QWidget>
+
+#include <coemain.h> // for CCoeEnv
+
+#include "abstractvideoplayer.h"
+#include "utils.h"
+
+#ifndef QT_NO_DEBUG
+#include "objectdump.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+/*! \class MMF::AbstractVideoPlayer
+ \internal
+*/
+
+//-----------------------------------------------------------------------------
+// Constructor / destructor
+//-----------------------------------------------------------------------------
+
+MMF::AbstractVideoPlayer::AbstractVideoPlayer(MediaObject *parent, const AbstractPlayer *player)
+ : AbstractMediaPlayer(parent, player)
+ , m_wsSession(CCoeEnv::Static()->WsSession())
+ , m_screenDevice(*CCoeEnv::Static()->ScreenDevice())
+ , m_window(0)
+ , m_scaleWidth(1.0)
+ , m_scaleHeight(1.0)
+ , m_totalTime(0)
+{
+
+}
+
+void MMF::AbstractVideoPlayer::construct()
+{
+ TRACE_CONTEXT(AbstractVideoPlayer::AbstractVideoPlayer, EVideoApi);
+ TRACE_ENTRY_0();
+
+ if (m_videoOutput) {
+ initVideoOutput();
+ m_window = m_videoOutput->videoWindow();
+ }
+
+ createPlayer();
+
+ m_player->RegisterForVideoLoadingNotification(*this);
+
+ TRACE_EXIT_0();
+}
+
+MMF::AbstractVideoPlayer::~AbstractVideoPlayer()
+{
+ TRACE_CONTEXT(AbstractVideoPlayer::~AbstractVideoPlayer, EVideoApi);
+ TRACE_ENTRY_0();
+
+ // QObject destructor removes all signal-slot connections involving this
+ // object, so we do not need to disconnect from m_videoOutput here.
+
+ TRACE_EXIT_0();
+}
+
+CVideoPlayerUtility* MMF::AbstractVideoPlayer::nativePlayer() const
+{
+ return m_player.data();
+}
+
+//-----------------------------------------------------------------------------
+// Public API
+//-----------------------------------------------------------------------------
+
+void MMF::AbstractVideoPlayer::doPlay()
+{
+ TRACE_CONTEXT(AbstractVideoPlayer::doPlay, EVideoApi);
+
+ handlePendingParametersChanged();
+
+ m_player->Play();
+}
+
+void MMF::AbstractVideoPlayer::doPause()
+{
+ TRACE_CONTEXT(AbstractVideoPlayer::doPause, EVideoApi);
+
+ TRAPD(err, m_player->PauseL());
+ if (KErrNone != err && state() != ErrorState) {
+ TRACE("PauseL error %d", err);
+ setError(tr("Pause failed"), err);
+ }
+}
+
+void MMF::AbstractVideoPlayer::doStop()
+{
+ m_player->Stop();
+}
+
+void MMF::AbstractVideoPlayer::doSeek(qint64 ms)
+{
+ TRACE_CONTEXT(AbstractVideoPlayer::doSeek, EVideoApi);
+
+ TRAPD(err, m_player->SetPositionL(TTimeIntervalMicroSeconds(ms * 1000)));
+
+ if (KErrNone != err)
+ setError(tr("Seek failed"), err);
+}
+
+int MMF::AbstractVideoPlayer::setDeviceVolume(int mmfVolume)
+{
+ TRAPD(err, m_player->SetVolumeL(mmfVolume));
+ return err;
+}
+
+int MMF::AbstractVideoPlayer::openFile(const QString &fileName)
+{
+ const QHBufC nativeFileName(QDir::toNativeSeparators(fileName));
+ TRAPD(err, m_player->OpenFileL(*nativeFileName));
+ return err;
+}
+
+int MMF::AbstractVideoPlayer::openFile(RFile &file)
+{
+ TRAPD(err, m_player->OpenFileL(file));
+ return err;
+}
+
+int MMF::AbstractVideoPlayer::openUrl(const QString &url, int iap)
+{
+ TRAPD(err, m_player->OpenUrlL(qt_QString2TPtrC(url), iap));
+ return err;
+}
+
+int MMF::AbstractVideoPlayer::openDescriptor(const TDesC8 &des)
+{
+ TRAPD(err, m_player->OpenDesL(des));
+ return err;
+}
+
+int MMF::AbstractVideoPlayer::bufferStatus() const
+{
+ int result = 0;
+ TRAP_IGNORE(m_player->GetVideoLoadingProgressL(result));
+ return result;
+}
+
+void MMF::AbstractVideoPlayer::doClose()
+{
+ m_player->Close();
+}
+
+bool MMF::AbstractVideoPlayer::hasVideo() const
+{
+ return true;
+}
+
+qint64 MMF::AbstractVideoPlayer::getCurrentTime() const
+{
+ TRACE_CONTEXT(AbstractVideoPlayer::getCurrentTime, EVideoApi);
+
+ TTimeIntervalMicroSeconds us;
+ TRAPD(err, us = m_player->PositionL())
+
+ qint64 result = 0;
+
+ if (KErrNone == err) {
+ result = toMilliSeconds(us);
+ } else {
+ TRACE("PositionL error %d", err);
+
+ // If we don't cast away constness here, we simply have to ignore
+ // the error.
+ const_cast<AbstractVideoPlayer*>(this)->setError(tr("Getting position failed"), err);
+ }
+
+ return result;
+}
+
+qint64 MMF::AbstractVideoPlayer::totalTime() const
+{
+ return m_totalTime;
+}
+
+
+//-----------------------------------------------------------------------------
+// Public slots
+//-----------------------------------------------------------------------------
+
+void MMF::AbstractVideoPlayer::videoWindowChanged()
+{
+ TRACE_CONTEXT(AbstractVideoPlayer::videoWindowChanged, EVideoInternal);
+ TRACE_ENTRY("state %d", state());
+
+ m_window = m_videoOutput ? m_videoOutput->videoWindow() : 0;
+
+ if (m_videoOutput)
+ m_videoOutput->dump();
+
+ handleVideoWindowChanged();
+
+ TRACE_EXIT_0();
+}
+
+void MMF::AbstractVideoPlayer::aspectRatioChanged()
+{
+ TRACE_CONTEXT(AbstractVideoPlayer::aspectRatioChanged, EVideoInternal);
+ TRACE_ENTRY("state %d aspectRatio %d", state());
+
+ if (m_videoOutput)
+ updateScaleFactors(m_videoOutput->videoWindowSize());
+
+ TRACE_EXIT_0();
+}
+
+void MMF::AbstractVideoPlayer::scaleModeChanged()
+{
+ TRACE_CONTEXT(AbstractVideoPlayer::scaleModeChanged, EVideoInternal);
+ TRACE_ENTRY("state %d", state());
+
+ if (m_videoOutput)
+ updateScaleFactors(m_videoOutput->videoWindowSize());
+
+ TRACE_EXIT_0();
+}
+
+
+//-----------------------------------------------------------------------------
+// MVideoPlayerUtilityObserver callbacks
+//-----------------------------------------------------------------------------
+
+void MMF::AbstractVideoPlayer::MvpuoOpenComplete(TInt aError)
+{
+ TRACE_CONTEXT(AbstractVideoPlayer::MvpuoOpenComplete, EVideoApi);
+ TRACE_ENTRY("state %d error %d", state(), aError);
+
+ __ASSERT_ALWAYS(LoadingState == state() ||
+ progressiveDownloadStalled() && BufferingState == state(),
+ Utils::panic(InvalidStatePanic));
+
+ if (KErrNone == aError)
+ m_player->Prepare();
+ else
+ setError(tr("Opening clip failed"), aError);
+
+ TRACE_EXIT_0();
+}
+
+void MMF::AbstractVideoPlayer::MvpuoPrepareComplete(TInt aError)
+{
+ TRACE_CONTEXT(AbstractVideoPlayer::MvpuoPrepareComplete, EVideoApi);
+ TRACE_ENTRY("state %d error %d", state(), aError);
+
+ __ASSERT_ALWAYS(LoadingState == state() ||
+ progressiveDownloadStalled() && BufferingState == state(),
+ Utils::panic(InvalidStatePanic));
+
+ TRAPD(err, getVideoClipParametersL(aError));
+
+ if (KErrNone == err) {
+ if (m_videoOutput)
+ m_videoOutput->dump();
+
+ maxVolumeChanged(m_player->MaxVolume());
+
+ if (m_videoOutput)
+ m_videoOutput->setVideoSize(m_videoFrameSize);
+
+ prepareCompleted();
+ handlePendingParametersChanged();
+
+ emit totalTimeChanged(totalTime());
+ }
+
+ loadingComplete(aError);
+
+ TRACE_EXIT_0();
+}
+
+void MMF::AbstractVideoPlayer::getVideoClipParametersL(TInt aError)
+{
+ User::LeaveIfError(aError);
+
+ // Get frame size
+ TSize size;
+ m_player->VideoFrameSizeL(size);
+ m_videoFrameSize = QSize(size.iWidth, size.iHeight);
+
+ // Get duration
+ m_totalTime = toMilliSeconds(m_player->DurationL());
+}
+
+
+void MMF::AbstractVideoPlayer::MvpuoFrameReady(CFbsBitmap &aFrame, TInt aError)
+{
+ TRACE_CONTEXT(AbstractVideoPlayer::MvpuoFrameReady, EVideoApi);
+ TRACE_ENTRY("state %d error %d", state(), aError);
+
+ Q_UNUSED(aFrame);
+ Q_UNUSED(aError); // suppress warnings in release builds
+
+ TRACE_EXIT_0();
+}
+
+void MMF::AbstractVideoPlayer::MvpuoPlayComplete(TInt aError)
+{
+ TRACE_CONTEXT(AbstractVideoPlayer::MvpuoPlayComplete, EVideoApi)
+ TRACE_ENTRY("state %d error %d", state(), aError);
+
+ // Call base class function which handles end of playback for both
+ // audio and video clips.
+ playbackComplete(aError);
+
+ TRACE_EXIT_0();
+}
+
+void MMF::AbstractVideoPlayer::MvpuoEvent(const TMMFEvent &aEvent)
+{
+ TRACE_CONTEXT(AbstractVideoPlayer::MvpuoEvent, EVideoApi);
+ TRACE_ENTRY("state %d", state());
+
+ Q_UNUSED(aEvent);
+
+ TRACE_EXIT_0();
+}
+
+
+//-----------------------------------------------------------------------------
+// MVideoLoadingObserver callbacks
+//-----------------------------------------------------------------------------
+
+void MMF::AbstractVideoPlayer::MvloLoadingStarted()
+{
+ bufferingStarted();
+}
+
+void MMF::AbstractVideoPlayer::MvloLoadingComplete()
+{
+ bufferingComplete();
+}
+
+
+//-----------------------------------------------------------------------------
+// Video window updates
+//-----------------------------------------------------------------------------
+
+void MMF::AbstractVideoPlayer::videoOutputChanged()
+{
+ TRACE_CONTEXT(AbstractVideoPlayer::videoOutputChanged, EVideoInternal);
+ TRACE_ENTRY_0();
+
+ if (m_videoOutput)
+ initVideoOutput();
+
+ videoWindowChanged();
+
+ TRACE_EXIT_0();
+}
+
+void MMF::AbstractVideoPlayer::initVideoOutput()
+{
+ Q_ASSERT(m_videoOutput);
+
+ bool connected = connect(
+ m_videoOutput, SIGNAL(videoWindowChanged()),
+ this, SLOT(videoWindowChanged())
+ );
+ Q_ASSERT(connected);
+
+ connected = connect(
+ m_videoOutput, SIGNAL(aspectRatioChanged()),
+ this, SLOT(aspectRatioChanged())
+ );
+ Q_ASSERT(connected);
+
+ connected = connect(
+ m_videoOutput, SIGNAL(scaleModeChanged()),
+ this, SLOT(scaleModeChanged())
+ );
+ Q_ASSERT(connected);
+
+ // Suppress warnings in release builds
+ Q_UNUSED(connected);
+
+ m_videoOutput->setVideoSize(m_videoFrameSize);
+}
+
+// Helper function for aspect ratio / scale mode handling
+QSize scaleToAspect(const QSize &srcRect, int aspectWidth, int aspectHeight)
+{
+ const qreal aspectRatio = qreal(aspectWidth) / aspectHeight;
+
+ int width = srcRect.width();
+ int height = srcRect.width() / aspectRatio;
+ if (height > srcRect.height()){
+ height = srcRect.height();
+ width = srcRect.height() * aspectRatio;
+ }
+ return QSize(width, height);
+}
+
+void MMF::AbstractVideoPlayer::updateScaleFactors(const QSize &windowSize, bool apply)
+{
+ Q_ASSERT(m_videoOutput);
+
+ if (m_videoFrameSize.isValid()) {
+ QRect videoRect;
+
+ // Calculate size of smallest rect which contains video frame size
+ // and conforms to aspect ratio
+ switch (m_videoOutput->aspectRatio()) {
+ case Phonon::VideoWidget::AspectRatioAuto:
+ videoRect.setSize(m_videoFrameSize);
+ break;
+
+ case Phonon::VideoWidget::AspectRatioWidget:
+ videoRect.setSize(windowSize);
+ break;
+
+ case Phonon::VideoWidget::AspectRatio4_3:
+ videoRect.setSize(scaleToAspect(m_videoFrameSize, 4, 3));
+ break;
+
+ case Phonon::VideoWidget::AspectRatio16_9:
+ videoRect.setSize(scaleToAspect(m_videoFrameSize, 16, 9));
+ break;
+ }
+
+ // Scale to fill the window width
+ const int windowWidth = windowSize.width();
+ const int windowHeight = windowSize.height();
+ const qreal windowScaleFactor = qreal(windowWidth) / videoRect.width();
+ int videoWidth = windowWidth;
+ int videoHeight = videoRect.height() * windowScaleFactor;
+
+ const qreal windowToVideoHeightRatio = qreal(windowHeight) / videoHeight;
+
+ switch (m_videoOutput->scaleMode()) {
+ case Phonon::VideoWidget::ScaleAndCrop:
+ if (videoHeight < windowHeight) {
+ videoWidth *= windowToVideoHeightRatio;
+ videoHeight = windowHeight;
+ }
+ break;
+ case Phonon::VideoWidget::FitInView:
+ default:
+ if (videoHeight > windowHeight) {
+ videoWidth *= windowToVideoHeightRatio;
+ videoHeight = windowHeight;
+ }
+ break;
+ }
+
+ // Calculate scale factors
+ m_scaleWidth = 100.0f * videoWidth / m_videoFrameSize.width();
+ m_scaleHeight = 100.0f * videoHeight / m_videoFrameSize.height();
+
+ if (apply)
+ parametersChanged(ScaleFactors);
+ }
+}
+
+void MMF::AbstractVideoPlayer::parametersChanged(VideoParameters parameters)
+{
+ if (state() == LoadingState || progressiveDownloadStalled() && BufferingState == state())
+ m_pendingChanges |= parameters;
+ else
+ handleParametersChanged(parameters);
+}
+
+void MMF::AbstractVideoPlayer::handlePendingParametersChanged()
+{
+ if (m_pendingChanges)
+ handleParametersChanged(m_pendingChanges);
+ m_pendingChanges = 0;
+}
+
+
+//-----------------------------------------------------------------------------
+// Metadata
+//-----------------------------------------------------------------------------
+
+int MMF::AbstractVideoPlayer::numberOfMetaDataEntries() const
+{
+ int numberOfEntries = 0;
+ TRAP_IGNORE(numberOfEntries = m_player->NumberOfMetaDataEntriesL());
+ return numberOfEntries;
+}
+
+QPair<QString, QString> MMF::AbstractVideoPlayer::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/abstractvideoplayer.h b/src/3rdparty/phonon/mmf/abstractvideoplayer.h
new file mode 100644
index 0000000..21446d2
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/abstractvideoplayer.h
@@ -0,0 +1,173 @@
+/* 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_ABSTRACTVIDEOPLAYER_H
+#define PHONON_MMF_ABSTRACTVIDEOPLAYER_H
+
+#include <videoplayer.h> // from epoc32/include
+
+#include <QSize>
+
+#include "abstractmediaplayer.h"
+#include "abstractvideooutput.h"
+#include "defs.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace MMF
+{
+/**
+ * @short ABC for classes which wrap the MMF video player utility
+ *
+ * On devices which use the legacy graphics subsystem which does not
+ * support surfaces, video rendering is done via Direct Screen Access using
+ * the CVideoPlayerUtility API. On devices with a graphics subsystem which
+ * does support surfaces, video rendering is done using the
+ * CVideoPlayerUtility2 API. Because CVideoPlayerUtility2 inherits from
+ * CVideoPlayerUtility, AbstractVideoPlayer holds a pointer to the latter.
+ *
+ * @see DsaVideoPlayer, SurfaceVideoPlayer
+ */
+class AbstractVideoPlayer
+ : public AbstractMediaPlayer
+ , public MVideoPlayerUtilityObserver
+ , public MVideoLoadingObserver
+{
+ Q_OBJECT
+
+public:
+ ~AbstractVideoPlayer();
+
+ typedef CVideoPlayerUtility NativePlayer;
+ NativePlayer *nativePlayer() const;
+
+ // AbstractPlayer
+ virtual void doPlay();
+ virtual void doPause();
+ virtual void doStop();
+ virtual void doSeek(qint64 milliseconds);
+ virtual int setDeviceVolume(int mmfVolume);
+ virtual int openFile(const QString &fileName);
+ virtual int openFile(RFile &file);
+ virtual int openUrl(const QString &url, int iap);
+ virtual int openDescriptor(const TDesC8 &des);
+ virtual int bufferStatus() const;
+ virtual void doClose();
+
+ // MediaObjectInterface
+ virtual bool hasVideo() const;
+ virtual qint64 totalTime() const;
+
+ // AbstractPlayer
+ virtual void videoOutputChanged();
+
+ // AbstractMediaPlayer
+ virtual qint64 getCurrentTime() const;
+ virtual int numberOfMetaDataEntries() const;
+ virtual QPair<QString, QString> metaDataEntry(int index) const;
+
+public Q_SLOTS:
+ void videoWindowChanged();
+ void aspectRatioChanged();
+ void scaleModeChanged();
+
+protected:
+ AbstractVideoPlayer(MediaObject *parent, const AbstractPlayer *player);
+ void construct();
+ virtual void initVideoOutput();
+ void updateScaleFactors(const QSize &windowSize, bool apply = true);
+
+ // Called when a video parameter changes. If the underlying native API is
+ // ready to handle the change, it is propagated immediately, otherwise the
+ // change is recorded in m_pendingChanged and handled later by
+ // handlePendingParametersChanged().
+ void parametersChanged(VideoParameters parameter);
+
+ // Implementation must initialize the m_player pointer.
+ virtual void createPlayer() = 0;
+
+ // Called from the MvpuoPrepareComplete callback. Allows derived class to
+ // calculate clipping rectangles and scale factors prior to starting
+ // playback.
+ virtual void prepareCompleted() = 0;
+
+ // Called when native video window handle changes. Derived class may defer
+ // propagation of this change to the MMF video player utility by calling
+ // parametersChanged().
+ virtual void handleVideoWindowChanged() = 0;
+
+ // Called when the derived class must handle changes which have been made
+ // to video parameters such as window handle, screen rectangle and scale
+ // factors. Guaranteed to be called only when the underlying MMF video
+ // player object is ready to handle changes to these parameters.
+ virtual void handleParametersChanged(VideoParameters parameters) = 0;
+
+private:
+ void getVideoClipParametersL(TInt aError);
+
+ // Called when native player API enters a state in which it is able to
+ // handle pending changes such as new video window handle, updated scale
+ // factors etc.
+ void handlePendingParametersChanged();
+
+private:
+ // MVideoPlayerUtilityObserver
+ virtual void MvpuoOpenComplete(TInt aError);
+ virtual void MvpuoPrepareComplete(TInt aError);
+ virtual void MvpuoFrameReady(CFbsBitmap &aFrame, TInt aError);
+ virtual void MvpuoPlayComplete(TInt aError);
+ virtual void MvpuoEvent(const TMMFEvent &aEvent);
+
+ // MVideoLoadingObserver
+ virtual void MvloLoadingStarted();
+ virtual void MvloLoadingComplete();
+
+protected:
+ QScopedPointer<NativePlayer> m_player;
+
+ // Not owned
+ RWsSession& m_wsSession;
+ CWsScreenDevice& m_screenDevice;
+ RWindowBase* m_window;
+
+ // Scaling factors for video display, expressed as percentages
+ TReal32 m_scaleWidth;
+ TReal32 m_scaleHeight;
+
+ // Dimensions of the video clip
+ QSize m_videoFrameSize;
+
+private:
+ // Bitmask of parameters which have changed while the MMF video player
+ // object is not yet ready to receive these changes.
+ // See handlePendingParametersChanged().
+ VideoParameters m_pendingChanges;
+
+ // Duration of the video clip
+ qint64 m_totalTime;
+
+};
+
+}
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/3rdparty/phonon/mmf/ancestormovemonitor.cpp b/src/3rdparty/phonon/mmf/ancestormovemonitor.cpp
new file mode 100644
index 0000000..f0d1be2
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/ancestormovemonitor.cpp
@@ -0,0 +1,179 @@
+/* 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_dsa.h"
+
+#include <QCoreApplication>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon::MMF;
+
+/*! \class Phonon::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
+*/
+
+
+/*! \class Phonon::MMF::VideoOutputObserver
+ \internal
+*/
+
+//-----------------------------------------------------------------------------
+// Constructor / destructor
+//-----------------------------------------------------------------------------
+
+AncestorMoveMonitor::AncestorMoveMonitor(QObject *parent)
+ : QObject(parent)
+{
+ QCoreApplication::instance()->installEventFilter(this);
+}
+
+AncestorMoveMonitor::~AncestorMoveMonitor()
+{
+ QCoreApplication::instance()->removeEventFilter(this);
+}
+
+
+//-----------------------------------------------------------------------------
+// Public functions
+//-----------------------------------------------------------------------------
+
+void AncestorMoveMonitor::registerTarget(DsaVideoOutput *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(DsaVideoOutput *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();
+ DsaVideoOutput* 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();
+ DsaVideoOutput* 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..f3a022d
--- /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 DsaVideoOutput;
+
+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(DsaVideoOutput *target);
+
+ /**
+ * Remove target from the monitor.
+ *
+ * The target will no longer receive notification when move events are
+ * delivered to its ancestors.
+ */
+ void unRegisterTarget(DsaVideoOutput *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<DsaVideoOutput *> 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 // !PHONON_MMF_ANCESTORMOVEMONITOR_H
diff --git a/src/3rdparty/phonon/mmf/audioequalizer.cpp b/src/3rdparty/phonon/mmf/audioequalizer.cpp
new file mode 100644
index 0000000..1d2bbd4
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/audioequalizer.cpp
@@ -0,0 +1,106 @@
+/* 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 <AudioEqualizerBase.h>
+#include "audioequalizer.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+/*! \class MMF::AudioEqualizer
+ \internal
+*/
+
+// Define functions which depend on concrete native effect class name
+PHONON_MMF_DEFINE_EFFECT_FUNCTIONS(AudioEqualizer)
+
+AudioEqualizer::AudioEqualizer(QObject *parent, const QList<EffectParameter>& parameters)
+ : AbstractAudioEffect::AbstractAudioEffect(parent, parameters)
+{
+
+}
+
+int AudioEqualizer::effectParameterChanged(const EffectParameter &param,
+ const QVariant &value)
+{
+ const int band = param.id() - ParameterBase + 1;
+
+ const qreal externalLevel = value.toReal();
+ const int internalLevel = param.toInternalValue(externalLevel);
+
+ TRAPD(err, concreteEffect()->SetBandLevelL(band, internalLevel));
+ return err;
+}
+
+
+//-----------------------------------------------------------------------------
+// Static functions
+//-----------------------------------------------------------------------------
+
+const char* AudioEqualizer::description()
+{
+ return "Audio equalizer";
+}
+
+bool AudioEqualizer::getParameters(CMdaAudioOutputStream *stream,
+ QList<EffectParameter>& parameters)
+{
+ bool supported = false;
+
+ QScopedPointer<CAudioEqualizer> effect;
+ TRAPD(err, effect.reset(CAudioEqualizer::NewL(*stream)));
+
+ if (KErrNone == err) {
+ supported = true;
+
+ TInt32 dbMin;
+ TInt32 dbMax;
+ effect->DbLevelLimits(dbMin, dbMax);
+
+ const int bandCount = effect->NumberOfBands();
+
+ for (int i = 0; i < bandCount; ++i) {
+ // For some reason, band IDs are 1-based, as opposed to the
+ // 0-based indices used in just about other Symbian API...!
+ const int band = i + 1;
+
+ const qint32 hz = effect->CenterFrequency(band);
+
+ // We pass a floating-point parameter range of -1.0 to +1.0 for
+ // each band in order to work around a limitation in
+ // Phonon::EffectWidget. See documentation of EffectParameter
+ // for more details.
+ EffectParameter param(
+ /* parameterId */ ParameterBase + i,
+ /* name */ tr("%1 Hz").arg(hz),
+ /* hints */ EffectParameter::LogarithmicHint,
+ /* defaultValue */ QVariant(qreal(0.0)),
+ /* minimumValue */ QVariant(qreal(-1.0)),
+ /* maximumValue */ QVariant(qreal(+1.0)));
+
+ param.setInternalRange(dbMin, dbMax);
+ parameters.append(param);
+ }
+ }
+
+ return supported;
+}
+
+QT_END_NAMESPACE
diff --git a/src/3rdparty/phonon/mmf/audioequalizer.h b/src/3rdparty/phonon/mmf/audioequalizer.h
new file mode 100644
index 0000000..9c3770a
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/audioequalizer.h
@@ -0,0 +1,67 @@
+/* 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_AUDIOEQUALIZER_H
+#define PHONON_MMF_AUDIOEQUALIZER_H
+
+#include "abstractaudioeffect.h"
+
+class CAudioEqualizer;
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace MMF
+{
+/**
+ * @short A classic equalizer.
+ *
+ * The equalizer has a number of bands, and each band has a frequency, and a
+ * volume. With Phonon's API, this is modeled such that each band is one
+ * Phonon::EffectParameter, where Phonon::EffectParameter::id() is the band
+ * number, and the setting is the volume level.
+ */
+class AudioEqualizer : public AbstractAudioEffect
+{
+ Q_OBJECT
+public:
+ AudioEqualizer(QObject *parent, const QList<EffectParameter> &parameters);
+
+ // Static interface required by EffectFactory
+ static const char* description();
+ static bool getParameters(CMdaAudioOutputStream *stream,
+ QList<EffectParameter>& parameters);
+
+protected:
+ // AbstractAudioEffect
+ virtual void createEffect(AudioPlayer::NativePlayer *player);
+ virtual int effectParameterChanged(const EffectParameter &param,
+ const QVariant &value);
+
+private:
+ CAudioEqualizer *concreteEffect();
+
+};
+}
+}
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/3rdparty/phonon/mmf/audiooutput.cpp b/src/3rdparty/phonon/mmf/audiooutput.cpp
new file mode 100644
index 0000000..3588683
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/audiooutput.cpp
@@ -0,0 +1,114 @@
+/* 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 <e32debug.h>
+
+#include <QCoreApplication>
+
+#include "audiooutput.h"
+#include "defs.h"
+#include "mediaobject.h"
+#include "utils.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+/*! \class MMF::AudioOutput
+ \internal
+*/
+
+//-----------------------------------------------------------------------------
+// Constructor / destructor
+//-----------------------------------------------------------------------------
+
+MMF::AudioOutput::AudioOutput(Backend *, QObject *parent) : MediaNode(parent)
+ , m_volume(InitialVolume)
+{
+
+}
+
+
+//-----------------------------------------------------------------------------
+// Public API
+//-----------------------------------------------------------------------------
+
+qreal MMF::AudioOutput::volume() const
+{
+ return m_volume;
+}
+
+void MMF::AudioOutput::setVolume(qreal volume)
+{
+ TRACE_CONTEXT(AudioOutput::setVolume, EAudioApi);
+ TRACE_ENTRY("volume %f", volume);
+
+ if (volume != m_volume) {
+
+ m_volume = volume;
+ TRACE("emit volumeChanged(%f)", volume)
+ emit volumeChanged(volume);
+ }
+
+ TRACE_EXIT_0();
+}
+
+int MMF::AudioOutput::outputDevice() const
+{
+ return AudioOutputDeviceID;
+}
+
+bool MMF::AudioOutput::setOutputDevice(int index)
+{
+ Q_ASSERT_X(index == AudioOutputDeviceID, Q_FUNC_INFO,
+ "We only support one output device, with id 0");
+#ifdef QT_NO_DEBUG
+ Q_UNUSED(index)
+#endif
+ return true;
+}
+
+void MMF::AudioOutput::connectMediaObject(MediaObject *mediaObject)
+{
+ // Ensure that the MediaObject has the correct initial volume
+ mediaObject->volumeChanged(m_volume);
+ // Connect MediaObject to receive future volume changes
+ connect(this, SIGNAL(volumeChanged(qreal)), mediaObject, SLOT(volumeChanged(qreal)));
+}
+
+void MMF::AudioOutput::disconnectMediaObject(MediaObject *mediaObject)
+{
+ // Disconnect all signal-slot connections
+ disconnect(this, 0, mediaObject, 0);
+}
+
+QHash<QByteArray, QVariant> MMF::AudioOutput::audioOutputDescription(int index)
+{
+ QHash<QByteArray, QVariant> retval;
+
+ if (index == AudioOutputDeviceID) {
+ retval.insert("name", QCoreApplication::translate("Phonon::MMF", "Audio Output"));
+ retval.insert("description", QCoreApplication::translate("Phonon::MMF", "The audio output device"));
+ retval.insert("available", true);
+ }
+
+ return retval;
+}
+
+QT_END_NAMESPACE
diff --git a/src/3rdparty/phonon/mmf/audiooutput.h b/src/3rdparty/phonon/mmf/audiooutput.h
new file mode 100644
index 0000000..67aaa38
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/audiooutput.h
@@ -0,0 +1,94 @@
+/* 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_AUDIOOUTPUT_H
+#define PHONON_MMF_AUDIOOUTPUT_H
+
+#include <QHash>
+
+#include "mmf_medianode.h"
+#include <phonon/audiooutputinterface.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace MMF
+{
+class Backend;
+
+/**
+ * @short AudioOutputInterface implementation for MMF.
+ *
+ * Forwards volume commands to the MediaObject instance,
+ * which is provided by the backend when MediaNode objects are
+ * connected.
+ *
+ * \section volume Volume
+ *
+ * Phonon's concept on volume is from 0.0 to 1.0, and from 1< it does
+ * voltage multiplication. CDrmPlayerUtility goes from 1 to
+ * CDrmPlayerUtility::MaxVolume(). We apply some basic math to convert
+ * between the two.
+ *
+ * @author Frans Englich<frans.englich@nokia.com>
+ */
+class AudioOutput : public MediaNode
+ , public AudioOutputInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(Phonon::AudioOutputInterface)
+
+public:
+ AudioOutput(Backend *backend, QObject *parent);
+ virtual qreal volume() const;
+ virtual void setVolume(qreal volume);
+
+ virtual int outputDevice() const;
+
+ /**
+ * Has no effect.
+ */
+ virtual bool setOutputDevice(int);
+
+ static QHash<QByteArray, QVariant> audioOutputDescription(int index);
+
+ enum Constants
+ {
+ AudioOutputDeviceID = 0
+ };
+
+protected:
+ // MediaNode
+ void connectMediaObject(MediaObject *mediaObject);
+ void disconnectMediaObject(MediaObject *mediaObject);
+
+Q_SIGNALS:
+ void volumeChanged(qreal volume);
+ void audioDeviceFailed();
+
+private:
+ qreal m_volume;
+
+};
+}
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/3rdparty/phonon/mmf/audioplayer.cpp b/src/3rdparty/phonon/mmf/audioplayer.cpp
new file mode 100644
index 0000000..2ae6a3d
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/audioplayer.cpp
@@ -0,0 +1,293 @@
+/* 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 <QDir>
+#include <QUrl>
+
+#include "audioplayer.h"
+#include "utils.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+/*! \class MMF::AudioPlayer
+ \internal
+*/
+
+//-----------------------------------------------------------------------------
+// Constructor / destructor
+//-----------------------------------------------------------------------------
+
+MMF::AudioPlayer::AudioPlayer(MediaObject *parent, const AbstractPlayer *player)
+ : AbstractMediaPlayer(parent, player)
+ , m_totalTime(0)
+{
+ construct();
+}
+
+void MMF::AudioPlayer::construct()
+{
+ TRACE_CONTEXT(AudioPlayer::AudioPlayer, EAudioApi);
+ TRACE_ENTRY_0();
+
+ NativePlayer *player = 0;
+ QT_TRAP_THROWING(player = NativePlayer::NewL(*this, 0, EMdaPriorityPreferenceNone));
+ m_player.reset(player);
+ m_player->RegisterForAudioLoadingNotification(*this);
+
+ TRACE_EXIT_0();
+}
+
+MMF::AudioPlayer::~AudioPlayer()
+{
+ TRACE_CONTEXT(AudioPlayer::~AudioPlayer, EAudioApi);
+ TRACE_ENTRY_0();
+
+ TRACE_EXIT_0();
+}
+
+MMF::AudioPlayer::NativePlayer *MMF::AudioPlayer::nativePlayer() const
+{
+ return m_player.data();
+}
+
+//-----------------------------------------------------------------------------
+// Public API
+//-----------------------------------------------------------------------------
+
+void MMF::AudioPlayer::doPlay()
+{
+ m_player->Play();
+}
+
+void MMF::AudioPlayer::doPause()
+{
+ m_player->Pause();
+}
+
+void MMF::AudioPlayer::doStop()
+{
+ m_player->Stop();
+}
+
+void MMF::AudioPlayer::doSeek(qint64 ms)
+{
+ m_player->SetPosition(TTimeIntervalMicroSeconds(ms * 1000));
+}
+
+int MMF::AudioPlayer::setDeviceVolume(int mmfVolume)
+{
+ /* In SDK 3.1, SetVolume() returns void. If we're compiling against
+ * 3.1, we handle it with ifdefs. However, if we compile against a later
+ * SDK but are _running_ against 3.1, we avoid returning from an undefined
+ * stack by doing a runtime check of the SDK version. */
+#if !defined(__SERIES60_31__)
+ const int err = m_player->SetVolume(mmfVolume);
+ if (QSysInfo::s60Version() >= QSysInfo::SV_S60_3_2)
+ return err;
+ else
+ return KErrNone;
+ #else
+ m_player->SetVolume(mmfVolume);
+ return KErrNone;
+#endif
+}
+
+int MMF::AudioPlayer::openFile(const QString &fileName)
+{
+ const QHBufC nativeFileName(QDir::toNativeSeparators(fileName));
+ TRAPD(err, m_player->OpenFileL(*nativeFileName));
+ return err;
+}
+
+int MMF::AudioPlayer::openFile(RFile& file)
+{
+ TRAPD(err, m_player->OpenFileL(file));
+
+#ifdef QT_PHONON_MMF_AUDIO_DRM
+ if (KErrNone == err) {
+ // There appears to be a bug in the CDrmPlayerUtility implementation (at least
+ // in S60 5.x) whereby the player does not check whether the loading observer
+ // pointer is null before dereferencing it. Therefore we must register for
+ // loading notification, even though we do nothing in the callback functions.
+ m_player->RegisterForAudioLoadingNotification(*this);
+ }
+#endif
+
+ return err;
+}
+
+int MMF::AudioPlayer::openUrl(const QString& /*url*/, int /*iap*/)
+{
+ // Streaming playback is generally not supported by the implementation
+ // of the audio player API, so we use CVideoPlayerUtility for both
+ // audio and video streaming.
+ Utils::panic(AudioUtilityUrlNotSupported);
+
+ // Silence warning
+ return 0;
+}
+
+int MMF::AudioPlayer::openDescriptor(const TDesC8 &des)
+{
+ TRAPD(err, m_player->OpenDesL(des));
+ return err;
+}
+
+int MMF::AudioPlayer::bufferStatus() const
+{
+ int result = 0;
+ TRAP_IGNORE(m_player->GetAudioLoadingProgressL(result));
+ return result;
+}
+
+void MMF::AudioPlayer::doClose()
+{
+ m_player->Close();
+}
+
+bool MMF::AudioPlayer::hasVideo() const
+{
+ return false;
+}
+
+qint64 MMF::AudioPlayer::getCurrentTime() const
+{
+ TRACE_CONTEXT(AudioPlayer::getCurrentTime, EAudioApi);
+
+ TTimeIntervalMicroSeconds us;
+ const TInt err = m_player->GetPosition(us);
+
+ qint64 result = 0;
+
+ if (KErrNone == err) {
+ result = toMilliSeconds(us);
+ } else {
+ TRACE("GetPosition err %d", err);
+
+ // If we don't cast away constness here, we simply have to ignore
+ // the error.
+ const_cast<AudioPlayer*>(this)->setError(tr("Getting position failed"), err);
+ }
+
+ return result;
+}
+
+qint64 MMF::AudioPlayer::totalTime() const
+{
+ return m_totalTime;
+}
+
+
+//-----------------------------------------------------------------------------
+// Symbian multimedia client observer callbacks
+//-----------------------------------------------------------------------------
+
+#ifdef QT_PHONON_MMF_AUDIO_DRM
+void MMF::AudioPlayer::MdapcInitComplete(TInt aError,
+ const TTimeIntervalMicroSeconds &)
+#else
+void MMF::AudioPlayer::MapcInitComplete(TInt aError,
+ const TTimeIntervalMicroSeconds &)
+#endif
+{
+ TRACE_CONTEXT(AudioPlayer::MapcInitComplete, EAudioInternal);
+ TRACE_ENTRY("state %d error %d", state(), aError);
+
+ __ASSERT_ALWAYS(LoadingState == state() ||
+ progressiveDownloadStalled() && BufferingState == state(),
+ Utils::panic(InvalidStatePanic));
+
+ if (KErrNone == aError) {
+ maxVolumeChanged(m_player->MaxVolume());
+ m_totalTime = toMilliSeconds(m_player->Duration());
+ emit totalTimeChanged(m_totalTime);
+ }
+
+ loadingComplete(aError);
+
+ TRACE_EXIT_0();
+}
+
+#ifdef QT_PHONON_MMF_AUDIO_DRM
+void MMF::AudioPlayer::MdapcPlayComplete(TInt aError)
+#else
+void MMF::AudioPlayer::MapcPlayComplete(TInt aError)
+#endif
+{
+ TRACE_CONTEXT(AudioPlayer::MapcPlayComplete, EAudioInternal);
+ TRACE_ENTRY("state %d error %d", state(), aError);
+
+ // Call base class function which handles end of playback for both
+ // audio and video clips.
+ playbackComplete(aError);
+
+ TRACE_EXIT_0();
+}
+
+#ifdef QT_PHONON_MMF_AUDIO_DRM
+void MMF::AudioPlayer::MaloLoadingStarted()
+{
+
+}
+
+void MMF::AudioPlayer::MaloLoadingComplete()
+{
+
+}
+#endif // QT_PHONON_MMF_AUDIO_DRM
+
+
+//-----------------------------------------------------------------------------
+// MAudioLoadingObserver callbacks
+//-----------------------------------------------------------------------------
+
+void MMF::AudioPlayer::MaloLoadingStarted()
+{
+ bufferingStarted();
+}
+
+void MMF::AudioPlayer::MaloLoadingComplete()
+{
+ bufferingComplete();
+}
+
+
+//-----------------------------------------------------------------------------
+// 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
new file mode 100644
index 0000000..e963c26
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/audioplayer.h
@@ -0,0 +1,124 @@
+/* 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_AUDIOPLAYER_H
+#define PHONON_MMF_AUDIOPLAYER_H
+
+#include "abstractmediaplayer.h"
+
+class CDrmPlayerUtility;
+class TTimeIntervalMicroSeconds;
+
+#ifdef QT_PHONON_MMF_AUDIO_DRM
+#include <drmaudiosampleplayer.h>
+typedef MDrmAudioPlayerCallback NativePlayerObserver;
+#else
+#include <mdaaudiosampleplayer.h>
+typedef MMdaAudioPlayerCallback NativePlayerObserver;
+#endif
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace MMF
+{
+/**
+ * @short Wrapper over MMF audio client utility
+ */
+class AudioPlayer : public AbstractMediaPlayer
+ , public NativePlayerObserver
+ , public MAudioLoadingObserver
+{
+ Q_OBJECT
+
+public:
+ AudioPlayer(MediaObject *parent = 0, const AbstractPlayer *player = 0);
+ virtual ~AudioPlayer();
+
+#ifdef QT_PHONON_MMF_AUDIO_DRM
+typedef CDrmPlayerUtility NativePlayer;
+#else
+typedef CMdaAudioPlayerUtility NativePlayer;
+#endif
+
+ NativePlayer *nativePlayer() const;
+
+ // AbstractMediaPlayer
+ virtual void doPlay();
+ virtual void doPause();
+ virtual void doStop();
+ virtual void doSeek(qint64 milliseconds);
+ virtual int setDeviceVolume(int mmfVolume);
+ virtual int openFile(const QString &fileName);
+ virtual int openFile(RFile& file);
+ virtual int openUrl(const QString& url, int iap);
+ virtual int openDescriptor(const TDesC8 &des);
+ virtual int bufferStatus() const;
+ virtual void doClose();
+
+ // MediaObjectInterface
+ virtual bool hasVideo() const;
+ virtual qint64 totalTime() const;
+
+ // AbstractMediaPlayer
+ virtual qint64 getCurrentTime() const;
+ virtual int numberOfMetaDataEntries() const;
+ virtual QPair<QString, QString> metaDataEntry(int index) const;
+
+ /**
+ * This class owns the pointer.
+ */
+ NativePlayer *player() const;
+
+private:
+ void construct();
+
+private:
+#ifdef QT_PHONON_MMF_AUDIO_DRM
+ // MDrmAudioPlayerCallback
+ virtual void MdapcInitComplete(TInt aError,
+ const TTimeIntervalMicroSeconds &aDuration);
+ virtual void MdapcPlayComplete(TInt aError);
+#else
+ // MMdaAudioPlayerCallback
+ virtual void MapcInitComplete(TInt aError,
+ const TTimeIntervalMicroSeconds &aDuration);
+ virtual void MapcPlayComplete(TInt aError);
+#endif
+
+ // MAudioLoadingObserver
+ virtual void MaloLoadingStarted();
+ virtual void MaloLoadingComplete();
+
+private:
+ /**
+ * Using CPlayerType typedef in order to be able to easily switch between
+ * CMdaAudioPlayerUtility and CDrmPlayerUtility
+ */
+ QScopedPointer<NativePlayer> m_player;
+
+ qint64 m_totalTime;
+
+};
+}
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/3rdparty/phonon/mmf/backend.cpp b/src/3rdparty/phonon/mmf/backend.cpp
new file mode 100644
index 0000000..2cec43b
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/backend.cpp
@@ -0,0 +1,223 @@
+/* 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 <QStringList>
+#include <QtPlugin>
+
+#include <apgcli.h> // for RApaLsSession
+#include <apmrec.h> // for CDataTypeArray
+#include <apmstd.h> // for TDataType
+
+#include "abstractaudioeffect.h"
+#include "audiooutput.h"
+#include "audioplayer.h"
+#include "backend.h"
+#include "effectfactory.h"
+#include "mediaobject.h"
+#include "utils.h"
+#include "videowidget.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+/*! \class MMF::Backend
+ \internal
+*/
+
+Backend::Backend(QObject *parent)
+ : QObject(parent)
+#ifndef PHONON_MMF_VIDEO_SURFACES
+ , m_ancestorMoveMonitor(new AncestorMoveMonitor(this))
+#endif
+ , m_effectFactory(new EffectFactory(this))
+{
+ TRACE_CONTEXT(Backend::Backend, EBackend);
+ TRACE_ENTRY_0();
+
+ setProperty("identifier", QLatin1String("phonon_mmf"));
+ setProperty("backendName", QLatin1String("MMF"));
+ setProperty("backendComment", QLatin1String("Backend using Symbian Multimedia Framework (MMF)"));
+ setProperty("backendVersion", QLatin1String("0.1"));
+ setProperty("backendWebsite", QLatin1String("http://qt.nokia.com/"));
+
+ TRACE_EXIT_0();
+}
+
+QObject *Backend::createObject(BackendInterface::Class c, QObject *parent, const QList<QVariant> &args)
+{
+ TRACE_CONTEXT(Backend::createObject, EBackend);
+ TRACE_ENTRY("class %d", c);
+
+ QObject* result = 0;
+
+ switch (c) {
+ case AudioOutputClass:
+ result = new AudioOutput(this, parent);
+ break;
+
+ case MediaObjectClass:
+ result = new MediaObject(parent);
+ break;
+
+ case VolumeFaderEffectClass:
+ case VisualizationClass:
+ case VideoDataOutputClass:
+ case EffectClass:
+ {
+ Q_ASSERT(args.count() == 1);
+ Q_ASSERT(args.first().type() == QVariant::Int);
+ const EffectFactory::Type type =
+ static_cast<EffectFactory::Type>(args.first().toInt());
+ return m_effectFactory->createAudioEffect(type, parent);
+ }
+
+ case VideoWidgetClass:
+ {
+ VideoWidget *widget = new VideoWidget(qobject_cast<QWidget *>(parent));
+#ifndef PHONON_MMF_VIDEO_SURFACES
+ widget->setAncestorMoveMonitor(m_ancestorMoveMonitor.data());
+#endif
+ result = widget;
+ }
+ break;
+
+ default:
+ TRACE_PANIC(InvalidBackendInterfaceClass);
+ }
+
+ TRACE_RETURN("0x%08x", result);
+}
+
+QList<int> Backend::objectDescriptionIndexes(ObjectDescriptionType type) const
+{
+ TRACE_CONTEXT(Backend::objectDescriptionIndexes, EAudioApi);
+ TRACE_ENTRY_0();
+ QList<int> retval;
+
+ switch(type)
+ {
+ case EffectType:
+ retval.append(m_effectFactory->effectIndexes());
+ break;
+ case AudioOutputDeviceType:
+ // We only have one possible output device, but we need at least
+ // one.
+ retval.append(AudioOutput::AudioOutputDeviceID);
+ break;
+ default:
+ ;
+ }
+
+ TRACE_EXIT_0();
+ return retval;
+}
+
+QHash<QByteArray, QVariant> Backend::objectDescriptionProperties(ObjectDescriptionType type, int index) const
+{
+ TRACE_CONTEXT(Backend::connectNodes, EBackend);
+
+ switch (type) {
+ case EffectType:
+ return m_effectFactory->audioEffectDescriptions(EffectFactory::Type(index));
+ case AudioOutputDeviceType:
+ return AudioOutput::audioOutputDescription(index);
+ default:
+ return QHash<QByteArray, QVariant>();
+ }
+}
+
+bool Backend::startConnectionChange(QSet<QObject *>)
+{
+ return true;
+}
+
+bool Backend::connectNodes(QObject *sourceObject, QObject *targetObject)
+{
+ TRACE_CONTEXT(Backend::connectNodes, EBackend);
+ TRACE_ENTRY("source 0x%08x target 0x%08x", sourceObject, targetObject);
+
+ MediaNode *const source = qobject_cast<MediaNode *>(sourceObject);
+ MediaNode *const target = qobject_cast<MediaNode *>(targetObject);
+
+ Q_ASSERT_X(source, Q_FUNC_INFO, "source is not a MediaNode");
+ Q_ASSERT_X(target, Q_FUNC_INFO, "target is not a MediaNode");
+
+ return source->connectOutput(target);
+}
+
+bool Backend::disconnectNodes(QObject *sourceObject, QObject *targetObject)
+{
+ TRACE_CONTEXT(Backend::disconnectNodes, EBackend);
+ TRACE_ENTRY("source 0x%08x target 0x%08x", sourceObject, targetObject);
+
+ MediaNode *const source = qobject_cast<MediaNode *>(sourceObject);
+ MediaNode *const target = qobject_cast<MediaNode *>(targetObject);
+
+ Q_ASSERT_X(source, Q_FUNC_INFO, "source is not a MediaNode");
+ Q_ASSERT_X(target, Q_FUNC_INFO, "target is not a MediaNode");
+
+ return source->disconnectOutput(target);
+}
+
+bool Backend::endConnectionChange(QSet<QObject *>)
+{
+ return true;
+}
+
+void getAvailableMimeTypesL(QStringList& result)
+{
+ RApaLsSession apaSession;
+ User::LeaveIfError(apaSession.Connect());
+ CleanupClosePushL(apaSession);
+
+ static const TInt DataTypeArrayGranularity = 8;
+ CDataTypeArray* array = new(ELeave) CDataTypeArray(DataTypeArrayGranularity);
+ CleanupStack::PushL(array);
+
+ apaSession.GetSupportedDataTypesL(*array);
+
+ for (TInt i = 0; i < array->Count(); ++i) {
+ const TPtrC mimeType = array->At(i).Des();
+ const MediaType mediaType = Utils::mimeTypeToMediaType(mimeType);
+ if (MediaTypeAudio == mediaType or MediaTypeVideo == mediaType) {
+ result.append(qt_TDesC2QString(mimeType));
+ }
+ }
+
+ CleanupStack::PopAndDestroy(2); // apaSession, array
+}
+
+QStringList Backend::availableMimeTypes() const
+{
+ QStringList result;
+
+ // There is no way to return an error from this function, so we just
+ // have to trap and ignore exceptions...
+ TRAP_IGNORE(getAvailableMimeTypesL(result));
+
+ result.sort();
+
+ return result;
+}
+
+Q_EXPORT_PLUGIN2(phonon_mmf, Phonon::MMF::Backend);
+
+QT_END_NAMESPACE
+
diff --git a/src/3rdparty/phonon/mmf/backend.h b/src/3rdparty/phonon/mmf/backend.h
new file mode 100644
index 0000000..a45c92a
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/backend.h
@@ -0,0 +1,70 @@
+/* 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_BACKEND_H
+#define PHONON_MMF_BACKEND_H
+
+#ifndef PHONON_MMF_VIDEO_SURFACES
+#include "ancestormovemonitor.h"
+#endif
+
+#include "effectfactory.h"
+
+#include <phonon/mediasource.h>
+#include <phonon/backendinterface.h>
+#include <QScopedPointer>
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace MMF
+{
+class Backend : public QObject
+ , public BackendInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(Phonon::BackendInterface)
+public:
+ Backend(QObject *parent = 0);
+
+ virtual QObject *createObject(BackendInterface::Class c, QObject *parent, const QList<QVariant> &args);
+ virtual QList<int> objectDescriptionIndexes(ObjectDescriptionType type) const;
+ virtual QHash<QByteArray, QVariant> objectDescriptionProperties(ObjectDescriptionType type, int index) const;
+ virtual bool startConnectionChange(QSet<QObject *>);
+ virtual bool connectNodes(QObject *, QObject *);
+ virtual bool disconnectNodes(QObject *, QObject *);
+ virtual bool endConnectionChange(QSet<QObject *>);
+ virtual QStringList availableMimeTypes() const;
+
+Q_SIGNALS:
+ void objectDescriptionChanged(ObjectDescriptionType);
+
+private:
+#ifndef PHONON_MMF_VIDEO_SURFACES
+ QScopedPointer<AncestorMoveMonitor> m_ancestorMoveMonitor;
+#endif
+ QScopedPointer<EffectFactory> m_effectFactory;
+
+};
+}
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/3rdparty/phonon/mmf/bassboost.cpp b/src/3rdparty/phonon/mmf/bassboost.cpp
new file mode 100644
index 0000000..67076f6
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/bassboost.cpp
@@ -0,0 +1,59 @@
+/* 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 <BassBoostBase.h>
+#include "bassboost.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+// Define functions which depend on concrete native effect class name
+PHONON_MMF_DEFINE_EFFECT_FUNCTIONS(BassBoost)
+
+/*! \class MMF::BassBoost
+ \internal
+*/
+
+BassBoost::BassBoost(QObject *parent, const QList<EffectParameter> &parameters)
+ : AbstractAudioEffect::AbstractAudioEffect(parent, parameters)
+{
+
+}
+
+//-----------------------------------------------------------------------------
+// Static functions
+//-----------------------------------------------------------------------------
+
+const char* BassBoost::description()
+{
+ return "Bass boost";
+}
+
+bool BassBoost::getParameters(CMdaAudioOutputStream *stream,
+ QList<EffectParameter> &parameters)
+{
+ Q_UNUSED(parameters)
+ QScopedPointer<CBassBoost> effect;
+ TRAPD(err, effect.reset(CBassBoost::NewL(*stream)));
+ return (KErrNone == err);
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/3rdparty/phonon/mmf/bassboost.h b/src/3rdparty/phonon/mmf/bassboost.h
new file mode 100644
index 0000000..fc40e21
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/bassboost.h
@@ -0,0 +1,60 @@
+/* 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_BASSBOOST_H
+#define PHONON_MMF_BASSBOOST_H
+
+#include "abstractaudioeffect.h"
+
+class CBassBoost;
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace MMF
+{
+/**
+ * @short A "bass boost" effect.
+ */
+class BassBoost : public AbstractAudioEffect
+{
+ Q_OBJECT
+public:
+ BassBoost(QObject *parent, const QList<EffectParameter> &parameters);
+
+ // Static interface required by EffectFactory
+ static const char* description();
+ static bool getParameters(CMdaAudioOutputStream *stream,
+ QList<EffectParameter>& parameters);
+
+protected:
+ // AbstractAudioEffect
+ virtual void createEffect(AudioPlayer::NativePlayer *player);
+
+private:
+ CBassBoost *concreteEffect();
+
+};
+}
+}
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/3rdparty/phonon/mmf/defs.h b/src/3rdparty/phonon/mmf/defs.h
new file mode 100644
index 0000000..1ed8250
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/defs.h
@@ -0,0 +1,52 @@
+/* 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_DEFS_H
+#define PHONON_MMF_DEFS_H
+
+#include <QtGlobal>
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace MMF
+{
+static const qint32 DefaultTickInterval = 10;
+static const qreal InitialVolume = 0.5;
+
+enum MediaType {
+ MediaTypeUnknown,
+ MediaTypeAudio,
+ MediaTypeVideo
+};
+
+enum VideoParameter {
+ WindowHandle = 0x1,
+ WindowScreenRect = 0x2,
+ ScaleFactors = 0x4
+};
+Q_DECLARE_FLAGS(VideoParameters, VideoParameter)
+Q_DECLARE_OPERATORS_FOR_FLAGS(VideoParameters)
+
+}
+}
+
+QT_END_NAMESPACE
+
+#endif // PHONON_MMF_DEFS_H
diff --git a/src/3rdparty/phonon/mmf/download.cpp b/src/3rdparty/phonon/mmf/download.cpp
new file mode 100644
index 0000000..f074d7f
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/download.cpp
@@ -0,0 +1,199 @@
+/* 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 "download.h"
+#include "utils.h"
+#include <QtCore/QDir>
+#include <QtCore/private/qcore_symbian_p.h>
+#include <mmf/common/mmfcontrollerframeworkbase.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+static const TBool InheritDownloads = EFalse;
+
+DownloadPrivate::DownloadPrivate(Download *parent)
+ : QObject(parent)
+ , m_parent(parent)
+ , m_download(0)
+ , m_length(0)
+{
+
+}
+
+DownloadPrivate::~DownloadPrivate()
+{
+ if (m_download)
+ m_download->Delete();
+ m_downloadManager.Disconnect();
+ m_downloadManager.Close();
+}
+
+bool DownloadPrivate::start(int iap)
+{
+ TRACE_CONTEXT(DownloadPrivate::start, EVideoApi);
+ Q_ASSERT(!m_download);
+ // Connect to download manager
+ RProcess process;
+ const TUid uid3 = process.SecureId();
+ TRAPD(err, m_downloadManager.ConnectL(uid3, *this, InheritDownloads));
+ TRACE("connect err %d", err);
+ if (KErrNone == err) {
+ // Start download
+ if (KUseDefaultIap != iap)
+ m_downloadManager.SetIntAttribute(EDlMgrIap, iap);
+ QHBufC url(m_parent->sourceUrl().toString());
+ TPtr8 url8 = url->Des().Collapse();
+ TRAP(err, m_download = &m_downloadManager.CreateDownloadL(url8));
+ TRACE("start err %d", err);
+ if (KErrNone == err)
+ m_download->Start();
+ }
+ return (KErrNone == err);
+}
+
+void DownloadPrivate::resume()
+{
+
+}
+
+void DownloadPrivate::HandleDMgrEventL(RHttpDownload &aDownload, THttpDownloadEvent aEvent)
+{
+ TRACE_CONTEXT(DownloadPrivate::HandleDMgrEventL, EVideoApi);
+ Q_ASSERT(&aDownload == m_download);
+ switch (aEvent.iDownloadState) {
+ case EHttpDlPaused:
+ if (EHttpContentTypeReceived == aEvent.iProgressState) {
+ TRACE_0("paused, content type received");
+ m_download->Start();
+ }
+ break;
+ case EHttpDlInprogress:
+ switch (aEvent.iProgressState) {
+ case EHttpProgResponseHeaderReceived:
+ {
+ TFileName fileName;
+ m_download->GetStringAttribute(EDlAttrDestFilename, fileName);
+ TRACE("in progress, response header received, filename %S", &fileName);
+ const QString fileNameQt = QDir::fromNativeSeparators(qt_TDesC2QString(fileName));
+ m_parent->downloadStarted(fileNameQt);
+ }
+ break;
+ case EHttpProgResponseBodyReceived:
+ {
+ TInt32 length = 0;
+ m_download->GetIntAttribute(EDlAttrDownloadedSize, length);
+ if (length != m_length) {
+ TRACE("in progress, length %d", length);
+ m_length = length;
+ emit lengthChanged(m_length);
+ }
+ }
+ break;
+ }
+ break;
+ case EHttpDlCompleted:
+ TRACE_0("complete");
+ m_parent->complete();
+ break;
+ case EHttpDlFailed:
+ TRACE_0("failed");
+ m_parent->error();
+ break;
+ }
+}
+
+Download::Download(const QUrl &url, QObject *parent)
+ : QObject(parent)
+ , m_private(new DownloadPrivate(this))
+ , m_sourceUrl(url)
+ , m_state(Idle)
+{
+ qRegisterMetaType<Download::State>();
+ connect(m_private, SIGNAL(lengthChanged(qint64)), this, SIGNAL(lengthChanged(qint64)));
+}
+
+Download::~Download()
+{
+
+}
+
+const QUrl &Download::sourceUrl() const
+{
+ return m_sourceUrl;
+}
+
+const QString &Download::targetFileName() const
+{
+ return m_targetFileName;
+}
+
+void Download::start(int iap)
+{
+ TRACE_CONTEXT(Download::start, EVideoApi);
+ TRACE_ENTRY_0();
+ Q_ASSERT(Idle == m_state);
+ const bool ok = m_private->start(iap);
+ setState(ok ? Initializing : Error);
+ TRACE_EXIT_0();
+}
+
+void Download::resume()
+{
+ TRACE_CONTEXT(Download::resume, EVideoApi);
+ TRACE_ENTRY_0();
+ m_private->resume();
+ TRACE_EXIT_0();
+}
+
+void Download::setState(State state)
+{
+ TRACE_CONTEXT(Download::setState, EVideoApi);
+ TRACE("oldState %d newState %d", m_state, state);
+ const State oldState = m_state;
+ m_state = state;
+ if (oldState != m_state)
+ emit stateChanged(m_state);
+}
+
+void Download::error()
+{
+ TRACE_CONTEXT(Download::error, EVideoApi);
+ TRACE_0("");
+ setState(Error);
+}
+
+void Download::downloadStarted(const QString &targetFileName)
+{
+ TRACE_CONTEXT(Download::downloadStarted, EVideoApi);
+ TRACE_0("downloadStarted");
+ m_targetFileName = targetFileName;
+ setState(Downloading);
+}
+
+void Download::complete()
+{
+ TRACE_CONTEXT(Download::complete, EVideoApi);
+ TRACE_0("");
+ setState(Complete);
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/3rdparty/phonon/mmf/download.h b/src/3rdparty/phonon/mmf/download.h
new file mode 100644
index 0000000..2ce54a8
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/download.h
@@ -0,0 +1,109 @@
+/* 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_DOWNLOAD_H
+#define PHONON_MMF_DOWNLOAD_H
+
+#include <QtCore/QMetaType>
+#include <QtCore/QString>
+#include <QtCore/QUrl>
+#include <downloadmgrclient.h>
+
+QT_FORWARD_DECLARE_CLASS(QByteArray)
+QT_FORWARD_DECLARE_CLASS(QFile)
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace MMF
+{
+
+class Download;
+
+class DownloadPrivate : public QObject
+ , public MHttpDownloadMgrObserver
+{
+ Q_OBJECT
+public:
+ DownloadPrivate(Download *parent);
+ ~DownloadPrivate();
+ bool start(int iap);
+ void resume();
+signals:
+ void error();
+ void targetFileNameChanged();
+ void lengthChanged(qint64 length);
+ void complete();
+private:
+ // MHttpDownloadMgrObserver
+ void HandleDMgrEventL(RHttpDownload &aDownload, THttpDownloadEvent aEvent);
+private:
+ Download *m_parent;
+ RHttpDownloadMgr m_downloadManager;
+ RHttpDownload *m_download;
+ qint64 m_length;
+};
+
+class Download : public QObject
+{
+ Q_OBJECT
+ friend class DownloadPrivate;
+public:
+ Download(const QUrl &url, QObject *parent = 0);
+ ~Download();
+ const QUrl &sourceUrl() const;
+ const QString &targetFileName() const;
+ void start(int iap);
+ void resume();
+
+ enum State {
+ Idle,
+ Initializing,
+ Downloading,
+ Complete,
+ Error
+ };
+
+signals:
+ void lengthChanged(qint64 length);
+ void stateChanged(Download::State state);
+
+private:
+ void setState(State state);
+
+ // Called by DownloadPrivate
+ void error();
+ void downloadStarted(const QString &targetFileName);
+ void complete();
+
+private:
+ DownloadPrivate *m_private;
+ QUrl m_sourceUrl;
+ QString m_targetFileName;
+ State m_state;
+};
+
+}
+}
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(Phonon::MMF::Download::State)
+
+#endif
diff --git a/src/3rdparty/phonon/mmf/dummyplayer.cpp b/src/3rdparty/phonon/mmf/dummyplayer.cpp
new file mode 100644
index 0000000..ba75b02
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/dummyplayer.cpp
@@ -0,0 +1,115 @@
+/* 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 "dummyplayer.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+/*! \class MMF::DummyPlayer
+ \internal
+*/
+
+//-----------------------------------------------------------------------------
+// Constructor / destructor
+//-----------------------------------------------------------------------------
+
+MMF::DummyPlayer::DummyPlayer(const AbstractPlayer *player)
+ : AbstractPlayer(player)
+{
+
+}
+
+
+//-----------------------------------------------------------------------------
+// MediaObjectInterface
+//-----------------------------------------------------------------------------
+
+void MMF::DummyPlayer::play()
+{
+
+}
+
+void MMF::DummyPlayer::pause()
+{
+
+}
+
+void MMF::DummyPlayer::stop()
+{
+
+}
+
+void MMF::DummyPlayer::seek(qint64)
+{
+
+}
+
+bool MMF::DummyPlayer::hasVideo() const
+{
+ return false;
+}
+
+bool MMF::DummyPlayer::isSeekable() const
+{
+ return false;
+}
+
+Phonon::State MMF::DummyPlayer::state() const
+{
+ return Phonon::LoadingState;
+}
+
+qint64 MMF::DummyPlayer::currentTime() const
+{
+ return 0;
+}
+
+Phonon::ErrorType MMF::DummyPlayer::errorType() const
+{
+ return Phonon::NoError;
+}
+
+qint64 MMF::DummyPlayer::totalTime() const
+{
+ return 0;
+}
+
+void MMF::DummyPlayer::open()
+{
+
+}
+
+void MMF::DummyPlayer::close()
+{
+
+}
+
+//-----------------------------------------------------------------------------
+// AbstractPlayer
+//-----------------------------------------------------------------------------
+
+void MMF::DummyPlayer::doSetTickInterval(qint32)
+{
+
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/3rdparty/phonon/mmf/dummyplayer.h b/src/3rdparty/phonon/mmf/dummyplayer.h
new file mode 100644
index 0000000..5b00411
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/dummyplayer.h
@@ -0,0 +1,69 @@
+/* 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_DUMMYPLAYER_H
+#define PHONON_MMF_DUMMYPLAYER_H
+
+#include "abstractplayer.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace MMF
+{
+class AudioOutput;
+
+/**
+ * @short Stub implementation of AbstractPlayer.
+ *
+ * The functions of this class are:
+ * - Allow MediaObject to call a subset of the MediaObjectInterface
+ * API, before SetSource has been called.
+ * - Cache any parameters which are set in this state (e.g.
+ * prefinish mark), so that they can be copied into the 'real'
+ * AbstractPlayer implementation once a source has been loaded.
+ */
+class DummyPlayer : public AbstractPlayer
+{
+public:
+ DummyPlayer(const AbstractPlayer *player = 0);
+
+ // MediaObjectInterface
+ virtual void play();
+ virtual void pause();
+ virtual void stop();
+ virtual void seek(qint64 milliseconds);
+ virtual bool hasVideo() const;
+ virtual bool isSeekable() const;
+ virtual qint64 currentTime() const;
+ virtual Phonon::State state() const;
+ virtual Phonon::ErrorType errorType() const;
+ virtual qint64 totalTime() const;
+
+ // AbstractPlayer
+ virtual void open();
+ virtual void close();
+ virtual void doSetTickInterval(qint32 interval);
+};
+}
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/3rdparty/phonon/mmf/effectfactory.cpp b/src/3rdparty/phonon/mmf/effectfactory.cpp
new file mode 100644
index 0000000..4643978
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/effectfactory.cpp
@@ -0,0 +1,215 @@
+/* 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 <QObject>
+#include <QCoreApplication>
+
+#include <mdaaudiooutputstream.h>
+
+#include "audioequalizer.h"
+#include "bassboost.h"
+#include "environmentalreverb.h"
+#include "loudness.h"
+#include "stereowidening.h"
+
+#include "effectfactory.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+/*! \class MMF::EffectFactory
+ \internal
+*/
+
+EffectFactory::EffectFactory(QObject *parent)
+ : QObject(parent)
+ , m_initialized(false)
+{
+
+}
+
+EffectFactory::~EffectFactory()
+{
+
+}
+
+//-----------------------------------------------------------------------------
+// Public functions
+//-----------------------------------------------------------------------------
+
+AbstractAudioEffect *EffectFactory::createAudioEffect(Type type,
+ QObject *parent)
+{
+ // Lazily initialize
+ if (!m_initialized)
+ initialize();
+
+ Q_ASSERT(parent);
+
+ const QList<EffectParameter>& parameters = data(type).m_parameters;
+
+ AbstractAudioEffect *effect = 0;
+
+ switch (type)
+ {
+ case TypeBassBoost:
+ effect = new BassBoost(parent, parameters);
+ break;
+ case TypeAudioEqualizer:
+ effect = new AudioEqualizer(parent, parameters);
+ break;
+ case TypeEnvironmentalReverb:
+ effect = new EnvironmentalReverb(parent, parameters);
+ break;
+ case TypeLoudness:
+ effect = new Loudness(parent, parameters);
+ break;
+ case TypeStereoWidening:
+ effect = new StereoWidening(parent, parameters);
+ break;
+
+ // Not implemented
+ case TypeDistanceAttenuation:
+ case TypeListenerOrientation:
+ case TypeSourceOrientation:
+ // Fall through
+ default:
+ Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown effect");
+ }
+
+ return effect;
+}
+
+QHash<QByteArray, QVariant> EffectFactory::audioEffectDescriptions(Type type)
+{
+ // Lazily initialize
+ if (!m_initialized)
+ initialize();
+
+ return data(type).m_descriptions;
+}
+
+QList<int> EffectFactory::effectIndexes()
+{
+ // Lazily initialize
+ if (!m_initialized)
+ initialize();
+
+ QList<int> result;
+
+ QHash<Type, EffectData>::const_iterator i = m_effectData.begin();
+ for ( ; i != m_effectData.end(); ++i)
+ if (i.value().m_supported)
+ result.append(i.key());
+
+ return result;
+}
+
+//-----------------------------------------------------------------------------
+// Private functions
+//-----------------------------------------------------------------------------
+
+#define INITIALIZE_EFFECT(Effect) \
+ { \
+ EffectData data = getData<Effect>(); \
+ m_effectData.insert(Type##Effect, data); \
+ }
+
+void EffectFactory::initialize()
+{
+ Q_ASSERT_X(!m_initialized, Q_FUNC_INFO, "Already initialized");
+
+ INITIALIZE_EFFECT(AudioEqualizer)
+ INITIALIZE_EFFECT(BassBoost)
+ INITIALIZE_EFFECT(EnvironmentalReverb)
+ INITIALIZE_EFFECT(Loudness)
+ INITIALIZE_EFFECT(StereoWidening)
+
+ m_initialized = true;
+}
+
+// This class is just a wrapper which allows us to instantiate a
+// CMdaAudioOutputStream object. This is done in order to allow the
+// effects API to query the DevSound implementation, to discover
+// which effects are supported and what parameters they take.
+// Ideally, we would use CMMFDevSound directly, but this class is not
+// available in the public S60 SDK.
+class OutputStreamFactory : public MMdaAudioOutputStreamCallback
+{
+public:
+ CMdaAudioOutputStream* create()
+ {
+ CMdaAudioOutputStream* stream = 0;
+ QT_TRAP_THROWING(stream = CMdaAudioOutputStream::NewL(*this));
+ return stream;
+ }
+private:
+ void MaoscOpenComplete(TInt /*aError*/) { }
+ void MaoscBufferCopied(TInt /*aError*/, const TDesC8& /*aBuffer*/) { }
+ void MaoscPlayComplete(TInt /*aError*/) { }
+};
+
+template<typename BackendNode>
+EffectFactory::EffectData EffectFactory::getData()
+{
+ EffectData data;
+
+ // Create a temporary CMdaAudioOutputStream object, so that the effects
+ // API can query DevSound to discover which effects are supported.
+ OutputStreamFactory streamFactory;
+ QScopedPointer<CMdaAudioOutputStream> stream(streamFactory.create());
+
+ EffectParameter param(
+ /* parameterId */ AbstractAudioEffect::ParameterEnable,
+ /* name */ tr("Enabled"),
+ /* hints */ EffectParameter::ToggledHint,
+ /* defaultValue */ QVariant(bool(true)));
+ data.m_parameters.append(param);
+
+ data.m_supported = BackendNode::getParameters(stream.data(),
+ data.m_parameters);
+ if (data.m_supported) {
+ const QString description = QCoreApplication::translate
+ ("Phonon::MMF::EffectFactory", BackendNode::description());
+ data.m_descriptions.insert("name", description);
+ data.m_descriptions.insert("description", description);
+ data.m_descriptions.insert("available", true);
+ }
+
+ // Sanity check to ensure that all parameter IDs are unique
+ QSet<int> ids;
+ foreach (param, data.m_parameters) {
+ Q_ASSERT_X(ids.find(param.id()) == ids.end(), Q_FUNC_INFO,
+ "Parameter list contains duplicates");
+ ids.insert(param.id());
+ }
+
+ return data;
+}
+
+const EffectFactory::EffectData& EffectFactory::data(Type type) const
+{
+ QHash<Type, EffectData>::const_iterator i = m_effectData.find(type);
+ Q_ASSERT_X(i != m_effectData.end(), Q_FUNC_INFO, "Effect data not found");
+ return i.value();
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/3rdparty/phonon/mmf/effectfactory.h b/src/3rdparty/phonon/mmf/effectfactory.h
new file mode 100644
index 0000000..dd4b58d
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/effectfactory.h
@@ -0,0 +1,101 @@
+/* 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_EFFECTFACTORY_H
+#define PHONON_MMF_EFFECTFACTORY_H
+
+#include "abstractaudioeffect.h"
+#include "effectparameter.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace MMF
+{
+
+/**
+ * @short Contains utility functions related to effects.
+ */
+class EffectFactory : public QObject
+{
+ Q_OBJECT
+
+public:
+ EffectFactory(QObject *parent);
+ ~EffectFactory();
+
+ enum Type
+ {
+ TypeAudioEqualizer = 0
+ , TypeBassBoost
+ , TypeDistanceAttenuation
+ , TypeEnvironmentalReverb
+ , TypeListenerOrientation
+ , TypeLoudness
+ , TypeSourceOrientation
+ , TypeStereoWidening
+ };
+
+ /**
+ * @short Creates an audio effect of type @p type.
+ */
+ AbstractAudioEffect *createAudioEffect(Type type, QObject *parent);
+
+ /**
+ * @short Return the properties for effect @p type.
+ *
+ * This handles the effects for
+ * BackendInterface::objectDescriptionProperties().
+ */
+ QHash<QByteArray, QVariant> audioEffectDescriptions(Type type);
+
+ /**
+ * @short Returns the indexes for the supported effects.
+ *
+ * This handles the effects for
+ * BackendInterface::objectDescriptionIndexes().
+ */
+ QList<int> effectIndexes();
+
+private:
+ void initialize();
+
+ struct EffectData
+ {
+ bool m_supported;
+ QHash<QByteArray, QVariant> m_descriptions;
+ QList<EffectParameter> m_parameters;
+ };
+
+ template<typename BackendNode> EffectData getData();
+ const EffectData& data(Type type) const;
+
+private:
+ bool m_initialized;
+ QHash<Type, EffectData> m_effectData;
+
+};
+
+}
+}
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/3rdparty/phonon/mmf/effectparameter.cpp b/src/3rdparty/phonon/mmf/effectparameter.cpp
new file mode 100644
index 0000000..17c1315
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/effectparameter.cpp
@@ -0,0 +1,71 @@
+/* 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 "effectparameter.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+/*! \class MMF::EffectParameter
+ \internal
+*/
+
+MMF::EffectParameter::EffectParameter()
+ : m_hasInternalRange(false)
+{
+
+}
+
+MMF::EffectParameter::EffectParameter(
+ int parameterId, const QString &name, Hints hints,
+ const QVariant &defaultValue, const QVariant &min,
+ const QVariant &max, const QVariantList &values,
+ const QString &description)
+ : Phonon::EffectParameter(parameterId, name, hints, defaultValue,
+ min, max, values, description)
+ , m_hasInternalRange(false)
+{
+
+}
+
+void MMF::EffectParameter::setInternalRange(qint32 min, qint32 max)
+{
+ Q_ASSERT_X(max >= min, Q_FUNC_INFO, "Invalid range");
+ m_internalRange = QPair<qint32, qint32>(min, max);
+ m_hasInternalRange = true;
+}
+
+qint32 MMF::EffectParameter::toInternalValue(qreal external) const
+{
+ Q_ASSERT_X(m_hasInternalRange, Q_FUNC_INFO, "Does not have internal range");
+ const qint32 range = m_internalRange.second - m_internalRange.first;
+ return m_internalRange.first + ((1.0 + external) / 2) * range;
+}
+
+qreal MMF::EffectParameter::toExternalValue
+ (qint32 value, qint32 min, qint32 max)
+{
+ Q_ASSERT_X(max >= min, Q_FUNC_INFO, "Invalid range");
+ const qint32 range = max - min;
+ return range == 0 ? 0.0 : ((2.0 * value - min) / range) - 1.0;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/3rdparty/phonon/mmf/effectparameter.h b/src/3rdparty/phonon/mmf/effectparameter.h
new file mode 100644
index 0000000..892ed4d
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/effectparameter.h
@@ -0,0 +1,74 @@
+/* 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_EFFECTPARAMETER_H
+#define PHONON_MMF_EFFECTPARAMETER_H
+
+#include <phonon/effectparameter.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace MMF
+{
+
+/**
+ * @short Parameter value for an audio effect
+ *
+ * The base class is extended in order to work around a shortcoming
+ * in Phonon::EffectWidget. This widget only displays sliders for
+ * parameters with numeric values if the variant type of the parameter
+ * is QReal and the range is exactly -1.0 to +1.0; otherwise, a
+ * spinbox is used to set numeric parameters. This is rather
+ * inconvenient for many effects, such as the audio equalizer, for
+ * which a slider is a much more natural UI control.
+ *
+ * For many such parameters, we therefore report the type to be QReal
+ * and the range to be -1.0 to +1.0. This class stores the actual
+ * integer range for the parameter, and provides the toInternalValue
+ * function for converting between the client-side floating point
+ * value and the internal integer value.
+ */
+class EffectParameter : public Phonon::EffectParameter
+{
+public:
+ EffectParameter();
+ EffectParameter(int parameterId, const QString &name, Hints hints,
+ const QVariant &defaultValue, const QVariant &min = QVariant(),
+ const QVariant &max = QVariant(), const QVariantList &values = QVariantList(),
+ const QString &description = QString());
+
+ void setInternalRange(qint32 min, qint32 max);
+ qint32 toInternalValue(qreal external) const;
+
+ static qreal toExternalValue(qint32 value, qint32 min, qint32 max);
+
+private:
+ bool m_hasInternalRange;
+ QPair<qint32, qint32> m_internalRange;
+
+};
+
+}
+}
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/3rdparty/phonon/mmf/environmentalreverb.cpp b/src/3rdparty/phonon/mmf/environmentalreverb.cpp
new file mode 100644
index 0000000..d4f5223
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/environmentalreverb.cpp
@@ -0,0 +1,212 @@
+/* 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 <EnvironmentalReverbBase.h>
+#include "environmentalreverb.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+/*! \class MMF::EnvironmentalReverb
+ \internal
+*/
+
+// Define functions which depend on concrete native effect class name
+PHONON_MMF_DEFINE_EFFECT_FUNCTIONS(EnvironmentalReverb)
+
+enum Parameters
+{
+ DecayHFRatio = AbstractAudioEffect::ParameterBase,
+ DecayTime,
+ Density,
+ Diffusion,
+ ReflectionsDelay,
+ ReflectionsLevel,
+ ReverbDelay,
+ ReverbLevel,
+ RoomHFLevel,
+ RoomLevel
+};
+
+EnvironmentalReverb::EnvironmentalReverb(QObject *parent, const QList<EffectParameter>& parameters)
+ : AbstractAudioEffect::AbstractAudioEffect(parent, parameters)
+{
+
+}
+
+int EnvironmentalReverb::effectParameterChanged(const EffectParameter &param,
+ const QVariant &value)
+{
+ const qreal externalLevel = value.toReal();
+ const int internalLevel = param.toInternalValue(externalLevel);
+
+ TInt err = 0;
+
+ switch(param.id()) {
+ case DecayHFRatio:
+ TRAP(err, concreteEffect()->SetDecayHFRatioL(internalLevel));
+ break;
+ case DecayTime:
+ TRAP(err, concreteEffect()->SetDecayTimeL(internalLevel));
+ break;
+ case Density:
+ TRAP(err, concreteEffect()->SetDensityL(internalLevel));
+ break;
+ case Diffusion:
+ TRAP(err, concreteEffect()->SetDiffusionL(internalLevel));
+ break;
+ case ReflectionsDelay:
+ TRAP(err, concreteEffect()->SetReflectionsDelayL(internalLevel));
+ break;
+ case ReflectionsLevel:
+ TRAP(err, concreteEffect()->SetReflectionsLevelL(internalLevel));
+ break;
+ case ReverbDelay:
+ TRAP(err, concreteEffect()->SetReverbDelayL(internalLevel));
+ break;
+ case ReverbLevel:
+ TRAP(err, concreteEffect()->SetReverbLevelL(internalLevel));
+ break;
+ case RoomHFLevel:
+ TRAP(err, concreteEffect()->SetRoomHFLevelL(internalLevel));
+ break;
+ case RoomLevel:
+ TRAP(err, concreteEffect()->SetRoomLevelL(internalLevel));
+ break;
+ default:
+ Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown parameter");
+ }
+
+ return err;
+}
+
+
+//-----------------------------------------------------------------------------
+// Static functions
+//-----------------------------------------------------------------------------
+
+const char* EnvironmentalReverb::description()
+{
+ return "Reverb";
+}
+
+// Internal helper function
+Phonon::MMF::EffectParameter createParameter(int id, const QString &name,
+ int defaultValue, int minValue, int maxValue,
+ Phonon::EffectParameter::Hint hint = Phonon::EffectParameter::IntegerHint)
+{
+ const qreal externalDefaultValue =
+ Phonon::MMF::EffectParameter::toExternalValue
+ (defaultValue, minValue, maxValue);
+
+ Phonon::MMF::EffectParameter param(id, name, hint,
+ /* defaultValue */ QVariant(externalDefaultValue),
+ /* minimumValue */ QVariant(qreal(-1.0)),
+ /* maximumValue */ QVariant(qreal(+1.0)));
+
+ param.setInternalRange(minValue, maxValue);
+ return param;
+}
+
+bool EnvironmentalReverb::getParameters(CMdaAudioOutputStream *stream,
+ QList<EffectParameter>& parameters)
+{
+ bool supported = false;
+
+ QScopedPointer<CEnvironmentalReverb> effect;
+ TRAPD(err, effect.reset(CEnvironmentalReverb::NewL(*stream)));
+
+ if (KErrNone == err) {
+ supported = true;
+
+ TInt32 min, max;
+ TUint32 umin, umax;
+
+ effect->DecayHFRatioRange(umin, umax);
+ //: DecayHFRatio: Ratio of high-frequency decay time to the value specified by
+ //: DecayTime.
+ parameters.append(createParameter(
+ DecayHFRatio, tr("Decay HF ratio (%)"), effect->DecayHFRatio(),
+ umin, umax));
+
+ effect->DecayTimeRange(umin, umax);
+ //: DecayTime: Time over which reverberation is diminished.
+ parameters.append(createParameter(
+ DecayTime, tr("Decay time (ms)"), effect->DecayTime(),
+ umin, umax));
+
+ //: Density Delay between first and subsequent reflections.
+ //: Note that the S60 platform documentation does not make clear
+ //: the distinction between this value and the Diffusion value.
+ parameters.append(createParameter(
+ Density, tr("Density (%)"), effect->Density(), 0, 100));
+
+ //: Diffusion: Delay between first and subsequent reflections.
+ //: Note that the S60 platform documentation does not make clear
+ //: the distinction between this value and the Density value.
+ parameters.append(createParameter(
+ Diffusion, tr("Diffusion (%)"), effect->Diffusion(), 0, 100));
+
+ //: ReflectionsDelay: Amount of delay between the arrival the direct
+ //: path from the source and the arrival of the first reflection.
+ parameters.append(createParameter(
+ ReflectionsDelay, tr("Reflections delay (ms)"),
+ effect->ReflectionsDelay(), 0, effect->ReflectionsDelayMax()));
+
+ effect->ReflectionLevelRange(min, max);
+ //: ReflectionsLevel: Amplitude of reflections. This value is
+ //: corrected by the RoomLevel to give the final reflection amplitude.
+ parameters.append(createParameter(
+ ReflectionsLevel, tr("Reflections level (mB)"),
+ effect->ReflectionsLevel(),
+ min, max, EffectParameter::LogarithmicHint));
+
+ //: ReverbDelay: Amount of time between arrival of the first
+ //: reflection and start of the late reverberation.
+ parameters.append(createParameter(
+ ReverbDelay, tr("Reverb delay (ms)"), effect->ReverbDelay(),
+ 0, effect->ReverbDelayMax()));
+
+ effect->ReverbLevelRange(min, max);
+ //: ReverbLevel Amplitude of reverberations. This value is
+ //: corrected by the RoomLevel to give the final reverberation
+ //: amplitude.
+ parameters.append(createParameter(
+ ReverbLevel, tr("Reverb level (mB)"), effect->ReverbLevel(),
+ min, max, EffectParameter::LogarithmicHint));
+
+ effect->RoomHFLevelRange(min, max);
+ //: RoomHFLevel: Amplitude of low-pass filter used to attenuate the
+ //: high frequency component of reflected sound.
+ parameters.append(createParameter(
+ RoomHFLevel, tr("Room HF level"), effect->RoomHFLevel(),
+ min, max));
+
+ effect->RoomLevelRange(min, max);
+ //: RoomLevel: Master volume control for all reflected sound.
+ parameters.append(createParameter(
+ RoomLevel, tr("Room level (mB)"), effect->RoomLevel(),
+ min, max, EffectParameter::LogarithmicHint));
+ }
+
+ return supported;
+}
+
+QT_END_NAMESPACE
diff --git a/src/3rdparty/phonon/mmf/environmentalreverb.h b/src/3rdparty/phonon/mmf/environmentalreverb.h
new file mode 100644
index 0000000..eab68c6
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/environmentalreverb.h
@@ -0,0 +1,62 @@
+/* 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_ENVIRONMENTALREVERB_H
+#define PHONON_MMF_ENVIRONMENTALREVERB_H
+
+#include "abstractaudioeffect.h"
+
+class CEnvironmentalReverb;
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace MMF
+{
+/**
+ * @short A reverb effect.
+ */
+class EnvironmentalReverb : public AbstractAudioEffect
+{
+ Q_OBJECT
+public:
+ EnvironmentalReverb(QObject *parent, const QList<EffectParameter>& parameters);
+
+ // Static interface required by EffectFactory
+ static const char* description();
+ static bool getParameters(CMdaAudioOutputStream *stream,
+ QList<EffectParameter>& parameters);
+
+protected:
+ // AbstractAudioEffect
+ virtual void createEffect(AudioPlayer::NativePlayer *player);
+ virtual int effectParameterChanged(const EffectParameter &param,
+ const QVariant &value);
+
+private:
+ CEnvironmentalReverb *concreteEffect();
+
+};
+}
+}
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/3rdparty/phonon/mmf/loudness.cpp b/src/3rdparty/phonon/mmf/loudness.cpp
new file mode 100644
index 0000000..ca05ab0
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/loudness.cpp
@@ -0,0 +1,59 @@
+/* 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 <LoudnessBase.h>
+#include "loudness.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+// Define functions which depend on concrete native effect class name
+PHONON_MMF_DEFINE_EFFECT_FUNCTIONS(Loudness)
+
+/*! \class MMF::Loudness
+ \internal
+*/
+
+Loudness::Loudness(QObject *parent, const QList<EffectParameter>& parameters)
+ : AbstractAudioEffect::AbstractAudioEffect(parent, parameters)
+{
+
+}
+
+//-----------------------------------------------------------------------------
+// Static functions
+//-----------------------------------------------------------------------------
+
+const char* Loudness::description()
+{
+ return "Loudness";
+}
+
+bool Loudness::getParameters(CMdaAudioOutputStream *stream,
+ QList<EffectParameter> &parameters)
+{
+ Q_UNUSED(parameters)
+ QScopedPointer<CLoudness> effect;
+ TRAPD(err, effect.reset(CLoudness::NewL(*stream)));
+ return (KErrNone == err);
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/3rdparty/phonon/mmf/loudness.h b/src/3rdparty/phonon/mmf/loudness.h
new file mode 100644
index 0000000..a688a67
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/loudness.h
@@ -0,0 +1,60 @@
+/* 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_LOUDNESS_H
+#define PHONON_MMF_LOUDNESS_H
+
+#include "abstractaudioeffect.h"
+
+class CLoudness;
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace MMF
+{
+/**
+ * @short A "loudness" effect.
+ */
+class Loudness : public AbstractAudioEffect
+{
+ Q_OBJECT
+public:
+ Loudness(QObject *parent, const QList<EffectParameter>& parameters);
+
+ // Static interface required by EffectFactory
+ static const char* description();
+ static bool getParameters(CMdaAudioOutputStream *stream,
+ QList<EffectParameter>& parameters);
+
+protected:
+ // AbstractAudioEffect
+ virtual void createEffect(AudioPlayer::NativePlayer *player);
+
+private:
+ CLoudness *concreteEffect();
+
+};
+}
+}
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/3rdparty/phonon/mmf/mediaobject.cpp b/src/3rdparty/phonon/mmf/mediaobject.cpp
new file mode 100644
index 0000000..9da94ee
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/mediaobject.cpp
@@ -0,0 +1,561 @@
+/* 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 "audiooutput.h"
+#include "audioplayer.h"
+#include "defs.h"
+#include "dummyplayer.h"
+#include "utils.h"
+#include "utils.h"
+
+#ifdef PHONON_MMF_VIDEO_SURFACES
+#include "videoplayer_surface.h"
+#else
+#include "videoplayer_dsa.h"
+#endif
+
+#include "videowidget.h"
+
+#include "mediaobject.h"
+
+#include <QDir>
+#include <QResource>
+#include <QUrl>
+#include <cdbcols.h>
+#include <cdblen.h>
+#include <commdb.h>
+#include <mmf/common/mmfcontrollerframeworkbase.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+/*! \class MMF::MediaObject
+ \internal
+*/
+
+//-----------------------------------------------------------------------------
+// Constructor / destructor
+//-----------------------------------------------------------------------------
+
+MMF::MediaObject::MediaObject(QObject *parent) : MMF::MediaNode::MediaNode(parent)
+ , m_recognizerOpened(false)
+ , m_nextSourceSet(false)
+ , m_file(0)
+ , m_resource(0)
+{
+ m_player.reset(new DummyPlayer());
+
+ TRACE_CONTEXT(MediaObject::MediaObject, EAudioApi);
+ TRACE_ENTRY_0();
+
+ const int err = m_fileServer.Connect();
+ QT_TRAP_THROWING(User::LeaveIfError(err));
+
+ parent->installEventFilter(this);
+ m_iap = KUseDefaultIap;
+
+ TRACE_EXIT_0();
+}
+
+MMF::MediaObject::~MediaObject()
+{
+ TRACE_CONTEXT(MediaObject::~MediaObject, EAudioApi);
+ TRACE_ENTRY_0();
+
+ parent()->removeEventFilter(this);
+ delete m_resource;
+
+ if (m_file)
+ m_file->Close();
+ delete m_file;
+
+ m_fileServer.Close();
+ m_recognizer.Close();
+
+ TRACE_EXIT_0();
+}
+
+
+//-----------------------------------------------------------------------------
+// Recognizer
+//-----------------------------------------------------------------------------
+
+bool MMF::MediaObject::openRecognizer()
+{
+ TRACE_CONTEXT(MediaObject::openRecognizer, EAudioInternal);
+
+ if (!m_recognizerOpened) {
+ TInt err = m_recognizer.Connect();
+ if (KErrNone != err) {
+ TRACE("RApaLsSession::Connect error %d", err);
+ return false;
+ }
+
+ // This must be called in order to be able to share file handles with
+ // the recognizer server (see fileMediaType function).
+ err = m_fileServer.ShareProtected();
+ if (KErrNone != err) {
+ TRACE("RFs::ShareProtected error %d", err);
+ return false;
+ }
+
+ m_recognizerOpened = true;
+ }
+
+ return true;
+}
+
+MMF::MediaType MMF::MediaObject::fileMediaType
+(const QString& fileName)
+{
+ TRACE_CONTEXT(MediaObject::fileMediaType, EAudioInternal);
+
+ MediaType result = MediaTypeUnknown;
+
+ if (openRecognizer()) {
+ TInt err = openFileHandle(fileName);
+ const QHBufC nativeFileName(QDir::toNativeSeparators(fileName));
+ if (KErrNone == err) {
+ TDataRecognitionResult recognizerResult;
+ err = m_recognizer.RecognizeData(*m_file, recognizerResult);
+ if (KErrNone == err) {
+ const TPtrC mimeType = recognizerResult.iDataType.Des();
+ result = Utils::mimeTypeToMediaType(mimeType);
+ } else {
+ TRACE("RApaLsSession::RecognizeData filename %S error %d", nativeFileName.data(), err);
+ }
+ } else {
+ TRACE("RFile::Open filename %S error %d", nativeFileName.data(), err);
+ }
+ }
+
+ return result;
+}
+
+int MMF::MediaObject::openFileHandle(const QString &fileName)
+{
+ TRACE_CONTEXT(MediaObject::openFileHandle, EAudioInternal);
+ const QHBufC nativeFileName(QDir::toNativeSeparators(fileName));
+ TRACE_ENTRY("filename %S", nativeFileName.data());
+ if (m_file)
+ m_file->Close();
+ delete m_file;
+ m_file = 0;
+ m_file = new RFile;
+ TInt err = m_file->Open(m_fileServer, *nativeFileName, EFileRead | EFileShareReadersOrWriters);
+ return err;
+}
+
+MMF::MediaType MMF::MediaObject::bufferMediaType(const uchar *data, qint64 size)
+{
+ TRACE_CONTEXT(MediaObject::bufferMediaType, EAudioInternal);
+ MediaType result = MediaTypeUnknown;
+ if (openRecognizer()) {
+ TDataRecognitionResult recognizerResult;
+ const TPtrC8 des(data, size);
+ const TInt err = m_recognizer.RecognizeData(KNullDesC, des, recognizerResult);
+ if (KErrNone == err) {
+ const TPtrC mimeType = recognizerResult.iDataType.Des();
+ result = Utils::mimeTypeToMediaType(mimeType);
+ } else {
+ TRACE("RApaLsSession::RecognizeData error %d", err);
+ }
+ }
+ return result;
+}
+
+//-----------------------------------------------------------------------------
+// MediaObjectInterface
+//-----------------------------------------------------------------------------
+
+void MMF::MediaObject::play()
+{
+ m_player->play();
+}
+
+void MMF::MediaObject::pause()
+{
+ m_player->pause();
+}
+
+void MMF::MediaObject::stop()
+{
+ m_player->stop();
+}
+
+void MMF::MediaObject::seek(qint64 ms)
+{
+ m_player->seek(ms);
+
+ if (state() == PausedState or state() == PlayingState) {
+ emit tick(currentTime());
+ }
+}
+
+qint32 MMF::MediaObject::tickInterval() const
+{
+ return m_player->tickInterval();
+}
+
+void MMF::MediaObject::setTickInterval(qint32 interval)
+{
+ m_player->setTickInterval(interval);
+}
+
+bool MMF::MediaObject::hasVideo() const
+{
+ return m_player->hasVideo();
+}
+
+bool MMF::MediaObject::isSeekable() const
+{
+ return m_player->isSeekable();
+}
+
+Phonon::State MMF::MediaObject::state() const
+{
+ return m_player->state();
+}
+
+qint64 MMF::MediaObject::currentTime() const
+{
+ return m_player->currentTime();
+}
+
+QString MMF::MediaObject::errorString() const
+{
+ return m_player->errorString();
+}
+
+Phonon::ErrorType MMF::MediaObject::errorType() const
+{
+ return m_player->errorType();
+}
+
+qint64 MMF::MediaObject::totalTime() const
+{
+ return m_player->totalTime();
+}
+
+MediaSource MMF::MediaObject::source() const
+{
+ return m_source;
+}
+
+void MMF::MediaObject::setSource(const MediaSource &source)
+{
+ switchToSource(source);
+}
+
+void MMF::MediaObject::switchToSource(const MediaSource &source)
+{
+ if (m_file)
+ m_file->Close();
+ delete m_file;
+ m_file = 0;
+
+ delete m_resource;
+ m_resource = 0;
+
+ createPlayer(source);
+ m_source = source;
+ m_player->open();
+ emit currentSourceChanged(m_source);
+}
+
+void MMF::MediaObject::createPlayer(const MediaSource &source)
+{
+ TRACE_CONTEXT(MediaObject::createPlayer, EAudioApi);
+ TRACE_ENTRY("state %d source.type %d", state(), source.type());
+ TRACE_ENTRY("source.type %d", source.type());
+
+ MediaType mediaType = MediaTypeUnknown;
+
+ AbstractPlayer* oldPlayer = m_player.data();
+
+ const bool oldPlayerHasVideo = oldPlayer->hasVideo();
+ const bool oldPlayerSeekable = oldPlayer->isSeekable();
+
+ QString errorMessage;
+
+ // Determine media type
+ switch (source.type()) {
+ case MediaSource::LocalFile:
+ mediaType = fileMediaType(source.fileName());
+ break;
+
+ case MediaSource::Url:
+ {
+ const QUrl url(source.url());
+ if (url.scheme() == QLatin1String("file")) {
+ mediaType = fileMediaType(url.toLocalFile());
+ }
+ else {
+ // Streaming playback is generally not supported by the implementation
+ // of the audio player API, so we use CVideoPlayerUtility for both
+ // audio and video streaming.
+ mediaType = MediaTypeVideo;
+ }
+ }
+ break;
+
+ case MediaSource::Invalid:
+ case MediaSource::Disc:
+ errorMessage = tr("Error opening source: type not supported");
+ break;
+
+ case MediaSource::Stream:
+ {
+ const QString fileName = source.url().toLocalFile();
+ if (fileName.startsWith(QLatin1String(":/")) || fileName.startsWith(QLatin1String("qrc://"))) {
+ Q_ASSERT(!m_resource);
+ m_resource = new QResource(fileName);
+ if (m_resource->isValid()) {
+ if (m_resource->isCompressed())
+ errorMessage = tr("Error opening source: resource is compressed");
+ else
+ mediaType = bufferMediaType(m_resource->data(), m_resource->size());
+ } else {
+ errorMessage = tr("Error opening source: resource not valid");
+ }
+ } else {
+ errorMessage = tr("Error opening source: type not supported");
+ }
+ }
+ break;
+
+ case MediaSource::Empty:
+ TRACE_0("Empty media source");
+ break;
+ }
+
+ if (oldPlayer)
+ oldPlayer->close();
+
+ AbstractPlayer* newPlayer = 0;
+
+ // Construct newPlayer using oldPlayer (if not 0) in order to copy
+ // parameters (volume, prefinishMark, transitionTime) which may have
+ // been set on oldPlayer.
+
+ switch (mediaType) {
+ case MediaTypeUnknown:
+ TRACE_0("Media type could not be determined");
+ newPlayer = new DummyPlayer(oldPlayer);
+ errorMessage = tr("Error opening source: media type could not be determined");
+ break;
+
+ case MediaTypeAudio:
+ newPlayer = new AudioPlayer(this, oldPlayer);
+ break;
+
+ case MediaTypeVideo:
+#ifdef PHONON_MMF_VIDEO_SURFACES
+ newPlayer = SurfaceVideoPlayer::create(this, oldPlayer);
+#else
+ newPlayer = DsaVideoPlayer::create(this, oldPlayer);
+#endif
+ break;
+ }
+
+ if (oldPlayer)
+ emit abstractPlayerChanged(0);
+ m_player.reset(newPlayer);
+ emit abstractPlayerChanged(newPlayer);
+
+ if (oldPlayerHasVideo != hasVideo()) {
+ emit hasVideoChanged(hasVideo());
+ }
+
+ if (oldPlayerSeekable != isSeekable()) {
+ emit seekableChanged(isSeekable());
+ }
+
+ connect(m_player.data(), SIGNAL(totalTimeChanged(qint64)), SIGNAL(totalTimeChanged(qint64)));
+ 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(bufferStatus(int)), SIGNAL(bufferStatus(int)));
+ connect(m_player.data(), SIGNAL(metaDataChanged(QMultiMap<QString,QString>)), SIGNAL(metaDataChanged(QMultiMap<QString,QString>)));
+ connect(m_player.data(), SIGNAL(aboutToFinish()), SIGNAL(aboutToFinish()));
+ connect(m_player.data(), SIGNAL(prefinishMarkReached(qint32)), SIGNAL(prefinishMarkReached(qint32)));
+ connect(m_player.data(), SIGNAL(prefinishMarkReached(qint32)), SLOT(handlePrefinishMarkReached(qint32)));
+ connect(m_player.data(), SIGNAL(tick(qint64)), SIGNAL(tick(qint64)));
+
+ // We need to call setError() after doing the connects, otherwise the
+ // error won't be received.
+ if (!errorMessage.isEmpty()) {
+ Q_ASSERT(m_player);
+ m_player->setError(errorMessage);
+ }
+
+ TRACE_EXIT_0();
+}
+
+void MMF::MediaObject::setNextSource(const MediaSource &source)
+{
+ m_nextSource = source;
+ m_nextSourceSet = true;
+}
+
+qint32 MMF::MediaObject::prefinishMark() const
+{
+ return m_player->prefinishMark();
+}
+
+void MMF::MediaObject::setPrefinishMark(qint32 mark)
+{
+ m_player->setPrefinishMark(mark);
+}
+
+qint32 MMF::MediaObject::transitionTime() const
+{
+ return m_player->transitionTime();
+}
+
+void MMF::MediaObject::setTransitionTime(qint32 time)
+{
+ m_player->setTransitionTime(time);
+}
+
+void MMF::MediaObject::volumeChanged(qreal volume)
+{
+ m_player->volumeChanged(volume);
+}
+
+RFile* MMF::MediaObject::file() const
+{
+ return m_file;
+}
+
+QResource* MMF::MediaObject::resource() const
+{
+ return m_resource;
+}
+
+//-----------------------------------------------------------------------------
+// MediaNode
+//-----------------------------------------------------------------------------
+
+void MMF::MediaObject::connectMediaObject(MediaObject * /*mediaObject*/)
+{
+ // This function should never be called - see MediaNode::setMediaObject()
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "Connection of MediaObject to MediaObject");
+}
+
+void MMF::MediaObject::disconnectMediaObject(MediaObject * /*mediaObject*/)
+{
+ // This function should never be called - see MediaNode::setMediaObject()
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "Disconnection of MediaObject from MediaObject");
+}
+
+
+//-----------------------------------------------------------------------------
+// Video output
+//-----------------------------------------------------------------------------
+
+void MMF::MediaObject::setVideoOutput(AbstractVideoOutput* videoOutput)
+{
+ m_player->setVideoOutput(videoOutput);
+}
+
+
+AbstractPlayer *MMF::MediaObject::abstractPlayer() const
+{
+ return m_player.data();
+}
+
+//-----------------------------------------------------------------------------
+// Playlist support
+//-----------------------------------------------------------------------------
+
+void MMF::MediaObject::switchToNextSource()
+{
+ if (m_nextSourceSet) {
+ m_nextSourceSet = false;
+ switchToSource(m_nextSource);
+ play();
+ } else {
+ emit finished();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// IAP support
+//-----------------------------------------------------------------------------
+
+int MMF::MediaObject::currentIAP() const
+{
+ return m_iap;
+}
+
+bool MMF::MediaObject::eventFilter(QObject *watched, QEvent *event)
+{
+ if (event->type() == QEvent::DynamicPropertyChange ) {
+ QDynamicPropertyChangeEvent* dynamicEvent = static_cast<QDynamicPropertyChangeEvent*>(event);
+ if (dynamicEvent->propertyName() == "InternetAccessPointName") {
+ QVariant value = watched->property("InternetAccessPointName");
+ if (value.isValid()) {
+ QString iapName = value.toString();
+ TRAPD(err, setIAPIdFromNameL(iapName));
+ if (err)
+ m_player->setError(tr("Failed to set requested IAP"), err);
+ }
+ }
+ }
+ return false;
+}
+
+void MMF::MediaObject::setIAPIdFromNameL(const QString& iapString)
+{
+ TRACE_CONTEXT(MediaObject::getIapIdFromName, EVideoInternal);
+ TBuf<KCommsDbSvrMaxColumnNameLength> iapDes = qt_QString2TPtrC(iapString);
+ CCommsDatabase *commsDb = CCommsDatabase::NewL(EDatabaseTypeIAP);
+ CleanupStack::PushL(commsDb);
+ commsDb->ShowHiddenRecords();
+ CCommsDbTableView *view = commsDb->OpenTableLC(TPtrC(IAP));
+ for (TInt l = view->GotoFirstRecord(); l != KErrNotFound; l = view->GotoNextRecord()) {
+ TBuf<KCommsDbSvrMaxColumnNameLength> iapName;
+ view->ReadTextL(TPtrC(COMMDB_NAME), iapName);
+ TRACE("found IAP %S", &iapName);
+ if (iapName.CompareF(iapDes) == 0) {
+ TUint32 uiap;
+ view->ReadUintL(TPtrC(COMMDB_ID), uiap);
+ TRACE("matched IAP %S, setting m_iap %d", &iapName, uiap);
+ m_iap = uiap;
+ break;
+ }
+ }
+ CleanupStack::PopAndDestroy(2); // commsDb, view
+}
+
+//-----------------------------------------------------------------------------
+// Other private functions
+//-----------------------------------------------------------------------------
+
+void MMF::MediaObject::handlePrefinishMarkReached(qint32 time)
+{
+ emit tick(time);
+}
+
+
+QT_END_NAMESPACE
+
diff --git a/src/3rdparty/phonon/mmf/mediaobject.h b/src/3rdparty/phonon/mmf/mediaobject.h
new file mode 100644
index 0000000..0ed70ff
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/mediaobject.h
@@ -0,0 +1,160 @@
+/* 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_MEDIAOBJECT_H
+#define PHONON_MMF_MEDIAOBJECT_H
+
+#include <phonon/mediasource.h>
+#include <phonon/mediaobjectinterface.h>
+#include <QScopedPointer>
+#include <QTimer>
+#include <QString>
+
+// For recognizer
+#include <apgcli.h>
+
+#include "abstractplayer.h"
+#include "mmf_medianode.h"
+#include "defs.h"
+
+QT_BEGIN_NAMESPACE
+
+class QResource;
+
+namespace Phonon
+{
+namespace MMF
+{
+class AbstractPlayer;
+class AbstractVideoOutput;
+
+/**
+ * @short Facade class which wraps MMF client utility instance
+ */
+class MediaObject : public MediaNode
+ , public MediaObjectInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(Phonon::MediaObjectInterface)
+
+public:
+ MediaObject(QObject *parent);
+ virtual ~MediaObject();
+
+ // MediaObjectInterface
+ virtual void play();
+ virtual void pause();
+ virtual void stop();
+ virtual void seek(qint64 milliseconds);
+ virtual qint32 tickInterval() const;
+ virtual void setTickInterval(qint32 interval);
+ virtual bool hasVideo() const;
+ 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;
+ virtual void setSource(const MediaSource &);
+ virtual void setNextSource(const MediaSource &source);
+ virtual qint32 prefinishMark() const;
+ virtual void setPrefinishMark(qint32);
+ virtual qint32 transitionTime() const;
+ virtual void setTransitionTime(qint32);
+
+ // MediaNode
+ void connectMediaObject(MediaObject *mediaObject);
+ void disconnectMediaObject(MediaObject *mediaObject);
+
+ /**
+ * This class owns the AbstractPlayer, and will delete it upon
+ * destruction.
+ */
+ AbstractPlayer *abstractPlayer() const;
+
+ void setVideoOutput(AbstractVideoOutput* videoOutput);
+
+ int openFileHandle(const QString &fileName);
+ RFile* file() const;
+ QResource* resource() const;
+ int currentIAP() const;
+
+public Q_SLOTS:
+ void volumeChanged(qreal volume);
+ void switchToNextSource();
+
+Q_SIGNALS:
+ void abstractPlayerChanged(AbstractPlayer *player);
+ void totalTimeChanged(qint64 length);
+ void hasVideoChanged(bool hasVideo);
+ void seekableChanged(bool seekable);
+ void bufferStatus(int);
+ void aboutToFinish();
+ void prefinishMarkReached(qint32 remaining);
+ // TODO: emit metaDataChanged from MediaObject
+ void metaDataChanged(const QMultiMap<QString, QString>& metaData);
+ void currentSourceChanged(const MediaSource& source);
+ void stateChanged(Phonon::State newState,
+ Phonon::State oldState);
+ void finished();
+ void tick(qint64 time);
+
+protected:
+ bool eventFilter(QObject *watched, QEvent *event);
+
+private Q_SLOTS:
+ void handlePrefinishMarkReached(qint32);
+
+private:
+ void switchToSource(const MediaSource &source);
+ void createPlayer(const MediaSource &source);
+ bool openRecognizer();
+ void setIAPIdFromNameL(const QString& iapString);
+
+ // Audio / video media type recognition
+ MediaType fileMediaType(const QString& fileName);
+ MediaType bufferMediaType(const uchar *data, qint64 size);
+ // TODO: urlMediaType function
+
+ static qint64 toMilliSeconds(const TTimeIntervalMicroSeconds &);
+
+private:
+
+ // Audio / video media type recognition
+ bool m_recognizerOpened;
+ RApaLsSession m_recognizer;
+ RFs m_fileServer;
+
+ MediaSource m_source;
+ MediaSource m_nextSource;
+ bool m_nextSourceSet;
+
+ RFile* m_file;
+ QResource* m_resource;
+
+ QScopedPointer<AbstractPlayer> m_player;
+ int m_iap;
+
+};
+}
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/3rdparty/phonon/mmf/mmf_medianode.cpp b/src/3rdparty/phonon/mmf/mmf_medianode.cpp
new file mode 100644
index 0000000..ca413d9
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/mmf_medianode.cpp
@@ -0,0 +1,152 @@
+/* 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 "mediaobject.h"
+
+#include "mmf_medianode.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+/*! \class MMF::MediaNode
+ \internal
+*/
+
+MMF::MediaNode::MediaNode(QObject *parent)
+ : QObject(parent)
+ , m_mediaObject(qobject_cast<MediaObject *>(this))
+ , m_input(0)
+{
+
+}
+
+MMF::MediaNode::~MediaNode()
+{
+ // Phonon framework ensures nodes are disconnected before being destroyed.
+ Q_ASSERT_X(!m_mediaObject, Q_FUNC_INFO,
+ "Media node not disconnected before destruction");
+}
+
+bool MMF::MediaNode::connectOutput(MediaNode *output)
+{
+ Q_ASSERT_X(output, Q_FUNC_INFO, "Null output pointer");
+
+ bool connected = false;
+
+ // Check that this connection will not result in a graph which
+ // containing more than one MediaObject
+ const bool mediaObjectMisMatch =
+ m_mediaObject
+ && output->m_mediaObject
+ && m_mediaObject != output->m_mediaObject;
+
+ const bool canConnect =
+ !output->isMediaObject()
+ && !output->m_input
+ && !m_outputs.contains(output);
+
+ if (canConnect && !mediaObjectMisMatch) {
+ output->m_input = this;
+ m_outputs += output;
+ updateMediaObject();
+ connected = true;
+ }
+
+ return connected;
+}
+
+bool MMF::MediaNode::disconnectOutput(MediaNode *output)
+{
+ Q_ASSERT_X(output, Q_FUNC_INFO, "Null output pointer");
+
+ bool disconnected = false;
+
+ if (m_outputs.contains(output) && this == output->m_input) {
+ output->m_input = 0;
+ const bool removed = m_outputs.removeOne(output);
+ Q_ASSERT_X(removed, Q_FUNC_INFO, "Output removal failed");
+
+ Q_ASSERT_X(!m_outputs.contains(output), Q_FUNC_INFO,
+ "Output list contains duplicate entries");
+
+ // Perform traversal across each of the two graphs separately
+ updateMediaObject();
+ output->updateMediaObject();
+
+ disconnected = true;
+ }
+
+ return disconnected;
+}
+
+bool MMF::MediaNode::isMediaObject() const
+{
+ return (qobject_cast<const MediaObject *>(this) != 0);
+}
+
+void MMF::MediaNode::updateMediaObject()
+{
+ QList<MediaNode *> nodes;
+ MediaObject *mediaObject = 0;
+
+ // Traverse the graph, collecting a list of nodes, and locating
+ // the MediaObject node, if present
+ visit(nodes, mediaObject);
+
+ MediaNode *node = 0;
+ foreach(node, nodes)
+ node->setMediaObject(mediaObject);
+}
+
+void MMF::MediaNode::setMediaObject(MediaObject *mediaObject)
+{
+ if(!isMediaObject() && m_mediaObject != mediaObject) {
+ if (!mediaObject)
+ disconnectMediaObject(m_mediaObject);
+ else {
+ Q_ASSERT_X(!m_mediaObject, Q_FUNC_INFO, "MediaObject already set");
+ connectMediaObject(mediaObject);
+ }
+ m_mediaObject = mediaObject;
+ }
+}
+
+void MMF::MediaNode::visit(QList<MediaNode *>& visited, MediaObject*& mediaObject)
+{
+ if (isMediaObject()) {
+ // There can never be more than one MediaObject per graph, due to the
+ // mediaObjectMisMatch test in connectOutput().
+ Q_ASSERT_X(!mediaObject, Q_FUNC_INFO, "MediaObject already found");
+ mediaObject = static_cast<MediaObject *>(this);
+ }
+
+ visited += this;
+
+ if (m_input && !visited.contains(m_input))
+ m_input->visit(visited, mediaObject);
+
+ MediaNode *output = 0;
+ foreach (output, m_outputs)
+ if (!visited.contains(output))
+ output->visit(visited, mediaObject);
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/3rdparty/phonon/mmf/mmf_medianode.h b/src/3rdparty/phonon/mmf/mmf_medianode.h
new file mode 100644
index 0000000..f2f64e0
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/mmf_medianode.h
@@ -0,0 +1,108 @@
+/* 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_MEDIANODE_H
+#define PHONON_MMF_MEDIANODE_H
+
+#include <QObject>
+#include <phonon/effectinterface.h>
+#include "audioplayer.h"
+
+QT_BEGIN_NAMESPACE
+
+/**
+ * @file mmf_medianode.h mmf_medianode.cpp
+ *
+ * This file starts with mmf_ in order to avoid clash with Phonon's
+ * medianode.h. The GStreamer backend has a file named medianode.h, but it
+ * isn't compiled with ABLD build system, which have problems with separating
+ * user and system include paths.
+ */
+
+namespace Phonon
+{
+namespace MMF
+{
+class MediaObject;
+
+/**
+ * @short Base class for all nodes in the MMF backend.
+ *
+ * MediaNode is the base class for all nodes created by the MMF
+ * backend.
+ *
+ * These nodes may be one of the following types:
+ *
+ * - MediaObject
+ * This represents the source of media data. It encapsulates the
+ * appropriate MMF client API for playing audio or video.
+ * - AudioOutput
+ * This represents the audio output device. Since the MMF client API
+ * does not expose the output device directly, this backend node
+ * simply forwards volume control commands to the MediaObject.
+ * - VideoWidget
+ * A native widget on which video will be rendered.
+ * - An audio effect, derived form AbstractAudioEffect
+ *
+ * Because the MMF API does not support the concept of a media filter graph,
+ * this class must ensure the following:
+ *
+ * - Each media graph contains at most one MediaObject instance.
+ * - Every non-MediaObject node holds a reference to the MediaObject. This
+ * allows commands to be sent through the graph to the encapsulated MMF client
+ * API.
+ */
+class MediaNode : public QObject
+{
+ Q_OBJECT
+public:
+ MediaNode(QObject *parent);
+ ~MediaNode();
+
+ bool connectOutput(MediaNode *output);
+ bool disconnectOutput(MediaNode *output);
+
+ virtual void connectMediaObject(MediaObject *mediaObject) = 0;
+ virtual void disconnectMediaObject(MediaObject *mediaObject) = 0;
+
+private:
+ bool isMediaObject() const;
+
+ void updateMediaObject();
+ void setMediaObject(MediaObject *mediaObject);
+
+ typedef QList<const MediaNode *> NodeList;
+ void visit(QList<MediaNode *>& visited, MediaObject*& mediaObject);
+
+private:
+ MediaObject * m_mediaObject;
+
+ // All nodes except MediaObject may have an input
+ MediaNode * m_input;
+
+ // Only MediaObject can have more than one output
+ QList<MediaNode *> m_outputs;
+};
+
+}
+}
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/3rdparty/phonon/mmf/objectdump.cpp b/src/3rdparty/phonon/mmf/objectdump.cpp
new file mode 100644
index 0000000..778cde9
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/objectdump.cpp
@@ -0,0 +1,525 @@
+/* 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 <QByteArray>
+#include <QDebug>
+#include <QHash>
+#include <QTextStream>
+#include <QWidget>
+
+#include "objectdump.h"
+#include "objecttree.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace ObjectDump
+{
+
+//-----------------------------------------------------------------------------
+// QObjectAnnotator
+//-----------------------------------------------------------------------------
+
+QAnnotator::~QAnnotator()
+{
+
+}
+
+
+//-----------------------------------------------------------------------------
+// Annotators
+//-----------------------------------------------------------------------------
+
+QList<QByteArray> QAnnotatorBasic::annotation(const QObject& object)
+{
+ QList<QByteArray> result;
+
+ QByteArray array;
+ QTextStream stream(&array);
+
+ stream << '[' << &object << ']';
+ stream << ' ';
+ stream << object.metaObject()->className();
+
+ if (object.objectName() != "")
+ stream << " \"" << object.objectName() << '"';
+
+ if (object.isWidgetType())
+ stream << " isWidget";
+
+ stream.flush();
+ result.append(array);
+ return result;
+}
+
+QList<QByteArray> QAnnotatorWidget::annotation(const QObject& object)
+{
+ QList<QByteArray> result;
+
+ const QWidget* widget = qobject_cast<const QWidget*>(&object);
+ if (widget) {
+
+ QByteArray array;
+ QTextStream stream(&array);
+
+ stream << "widget: ";
+
+ if (widget->isVisible())
+ stream << "visible ";
+ else
+ stream << "invisible ";
+
+ stream << widget->x() << ',' << widget->y() << ' ';
+ stream << widget->size().width() << 'x'<< widget->size().height() << ' ';
+
+ stream << "hint " << widget->sizeHint().width() << 'x' << widget->sizeHint().height();
+
+ stream.flush();
+ result.append(array);
+ }
+
+ return result;
+}
+
+
+//-----------------------------------------------------------------------------
+// Base class for QDumperPrivate, QVisitorPrivate
+//-----------------------------------------------------------------------------
+
+class QDumperBase
+{
+public:
+ QDumperBase();
+ ~QDumperBase();
+
+ void setPrefix(const QString& prefix);
+ void addAnnotator(QAnnotator* annotator);
+
+protected:
+ QByteArray m_prefix;
+ QList<QAnnotator*> m_annotators;
+
+};
+
+QDumperBase::QDumperBase()
+{
+
+}
+
+QDumperBase::~QDumperBase()
+{
+ QAnnotator* annotator;
+ foreach(annotator, m_annotators)
+ delete annotator;
+}
+
+void QDumperBase::setPrefix(const QString& prefix)
+{
+ m_prefix = prefix.count()
+ ? (prefix + " ").toAscii()
+ : prefix.toAscii();
+}
+
+void QDumperBase::addAnnotator(QAnnotator* annotator)
+{
+ // Protect against an exception occurring during QList::append
+ QScopedPointer<QAnnotator> holder(annotator);
+ m_annotators.append(annotator);
+ holder.take();
+}
+
+
+//-----------------------------------------------------------------------------
+// QDumper
+//-----------------------------------------------------------------------------
+
+class QDumperPrivate : public QDumperBase
+{
+public:
+ QDumperPrivate();
+ ~QDumperPrivate();
+
+ void dumpObject(const QObject& object);
+
+};
+
+
+QDumperPrivate::QDumperPrivate()
+{
+
+}
+
+QDumperPrivate::~QDumperPrivate()
+{
+
+}
+
+void QDumperPrivate::dumpObject(const QObject& object)
+{
+ QAnnotator* annotator;
+ foreach(annotator, m_annotators) {
+
+ const QList<QByteArray> annotations = annotator->annotation(object);
+ QByteArray annotation;
+ foreach(annotation, annotations) {
+ QByteArray buffer(m_prefix);
+ buffer.append(annotation);
+ qDebug() << buffer.constData();
+ }
+ }
+}
+
+
+QDumper::QDumper()
+ : d_ptr(new QDumperPrivate)
+{
+
+}
+
+QDumper::~QDumper()
+{
+
+}
+
+void QDumper::setPrefix(const QString& prefix)
+{
+ d_func()->setPrefix(prefix);
+}
+
+void QDumper::addAnnotator(QAnnotator* annotator)
+{
+ d_func()->addAnnotator(annotator);
+}
+
+void QDumper::dumpObject(const QObject& object)
+{
+ d_func()->dumpObject(object);
+}
+
+
+//-----------------------------------------------------------------------------
+// QVisitor
+//-----------------------------------------------------------------------------
+
+class QVisitorPrivate : public QDumperBase
+{
+public:
+ QVisitorPrivate();
+ ~QVisitorPrivate();
+
+ void setIndent(unsigned indent);
+
+ void visitNode(const QObject& object);
+ void visitComplete();
+
+private:
+ class Node
+ {
+ public:
+ Node();
+ ~Node();
+
+ QList<QByteArray> m_annotation;
+ QList<Node*> m_children;
+
+ typedef QList<Node*>::const_iterator child_iterator;
+ };
+
+private:
+ Node* findNode(const QObject* object) const;
+ QByteArray branchBuffer(const QList<bool>& branches, bool isNodeLine, bool isLastChild) const;
+ void dumpRecursive(const Node& node, QList<bool> branches, bool isLastChild);
+ void dumpNode(const Node& node, const QList<bool>& branches, bool isLastChild);
+
+private:
+ unsigned m_indent;
+
+ QScopedPointer<Node> m_root;
+
+ // Hash table used to associate internal nodes with QObjects
+ typedef QHash<const QObject*, Node*> Hash;
+ Hash m_hash;
+};
+
+static const unsigned DefaultIndent = 2;
+
+QVisitorPrivate::QVisitorPrivate()
+ : m_indent(DefaultIndent)
+{
+
+}
+
+QVisitorPrivate::~QVisitorPrivate()
+{
+
+}
+
+void QVisitorPrivate::setIndent(unsigned indent)
+{
+ m_indent = indent;
+}
+
+// Builds up a mirror of the object tree, rooted in m_root, with each node
+// storing annotations generated by
+void QVisitorPrivate::visitNode(const QObject& object)
+{
+ QObject* const objectParent = object.parent();
+ Node* const nodeParent = objectParent ? findNode(objectParent) : 0;
+
+ // Create a new node and store in scoped pointer for exception safety
+ Node* node = new Node;
+ QScopedPointer<Node> nodePtr(node);
+
+ // Associate node with QObject
+ m_hash.insert(&object, node);
+
+ // Insert node into internal tree
+ if (nodeParent)
+ {
+ nodeParent->m_children.append(nodePtr.take());
+ }
+ else
+ {
+ Q_ASSERT(m_root.isNull());
+ m_root.reset(nodePtr.take());
+ }
+
+ // Generate and store annotations
+ QAnnotator* annotator;
+ foreach(annotator, m_annotators)
+ node->m_annotation.append( annotator->annotation(object) );
+}
+
+void QVisitorPrivate::visitComplete()
+{
+ QList<bool> branches;
+ static const bool isLastChild = true;
+ dumpRecursive(*m_root, branches, isLastChild);
+ m_root.reset(0);
+}
+
+QVisitorPrivate::Node* QVisitorPrivate::findNode(const QObject* object) const
+{
+ Hash::const_iterator i = m_hash.find(object);
+ return (m_hash.end() == i) ? 0 : *i;
+}
+
+QByteArray QVisitorPrivate::branchBuffer
+ (const QList<bool>& branches, bool isNodeLine, bool isLastChild) const
+{
+ const int depth = branches.count();
+
+ const QByteArray indent(m_indent, ' ');
+ const QByteArray horiz(m_indent, '-');
+
+ QByteArray buffer;
+ QTextStream stream(&buffer);
+
+ for (int i=0; i<depth-1; ++i) {
+ if (branches[i])
+ stream << '|';
+ else
+ stream << ' ';
+ stream << indent;
+ }
+
+ if (depth) {
+ if (isNodeLine)
+ stream << '+' << horiz;
+ else {
+ if (!isLastChild)
+ stream << '|';
+ else
+ stream << ' ';
+ stream << indent;
+ }
+ }
+
+ stream.flush();
+ buffer.push_front(m_prefix);
+
+ return buffer;
+}
+
+void QVisitorPrivate::dumpRecursive
+ (const Node& node, QList<bool> branches, bool isLastChild)
+{
+ dumpNode(node, branches, isLastChild);
+
+ // Recurse down tree
+ const Node::child_iterator begin = node.m_children.begin();
+ const Node::child_iterator end = node.m_children.end();
+ for (Node::child_iterator i = begin; end != i; ++i) {
+
+ isLastChild = (end == i + 1);
+
+ if (begin == i)
+ branches.push_back(!isLastChild);
+ else
+ branches.back() = !isLastChild;
+
+ static const bool isNodeLine = false;
+ const QByteArray buffer = branchBuffer(branches, isNodeLine, false);
+ qDebug() << buffer.constData();
+
+ dumpRecursive(**i, branches, isLastChild);
+ }
+}
+
+void QVisitorPrivate::dumpNode
+ (const Node& node, const QList<bool>& branches, bool isLastChild)
+{
+ const QList<QByteArray>::const_iterator
+ begin = node.m_annotation.begin(), end = node.m_annotation.end();
+
+ if (begin == end) {
+ // No annotations - just dump the object pointer
+ const bool isNodeLine = true;
+ QByteArray buffer = branchBuffer(branches, isNodeLine, isLastChild);
+ qDebug() << 0;
+ }
+ else {
+ // Dump annotations
+ for (QList<QByteArray>::const_iterator i = begin; end != i; ++i) {
+ const bool isNodeLine = (begin == i);
+ QByteArray buffer = branchBuffer(branches, isNodeLine, isLastChild);
+ buffer.append(*i);
+ qDebug() << buffer.constData();
+ }
+ }
+}
+
+
+// QVisitorPrivate::Node
+
+QVisitorPrivate::Node::Node()
+{
+
+}
+
+QVisitorPrivate::Node::~Node()
+{
+ Node* child;
+ foreach(child, m_children)
+ delete child;
+}
+
+
+// QVisitor
+
+QVisitor::QVisitor()
+ : d_ptr(new QVisitorPrivate)
+{
+
+}
+
+QVisitor::~QVisitor()
+{
+
+}
+
+void QVisitor::setPrefix(const QString& prefix)
+{
+ d_func()->setPrefix(prefix);
+}
+
+void QVisitor::setIndent(unsigned indent)
+{
+ d_func()->setIndent(indent);
+}
+
+void QVisitor::addAnnotator(QAnnotator* annotator)
+{
+ d_func()->addAnnotator(annotator);
+}
+
+void QVisitor::visitPrepare()
+{
+ // Do nothing
+}
+
+void QVisitor::visitNode(const QObject& object)
+{
+ d_func()->visitNode(object);
+}
+
+void QVisitor::visitComplete()
+{
+ d_func()->visitComplete();
+}
+
+
+//-----------------------------------------------------------------------------
+// Utility functions
+//-----------------------------------------------------------------------------
+
+void addDefaultAnnotators_sys(QDumper& visitor);
+void addDefaultAnnotators_sys(QVisitor& visitor);
+
+void addDefaultAnnotators(QDumper& dumper)
+{
+ dumper.addAnnotator(new QAnnotatorBasic);
+ dumper.addAnnotator(new QAnnotatorWidget);
+
+ // Add platform-specific annotators
+ addDefaultAnnotators_sys(dumper);
+}
+
+void addDefaultAnnotators(QVisitor& visitor)
+{
+ visitor.addAnnotator(new QAnnotatorBasic);
+ visitor.addAnnotator(new QAnnotatorWidget);
+
+ // Add platform-specific annotators
+ addDefaultAnnotators_sys(visitor);
+}
+
+void dumpTreeFromRoot(const QObject& root, QVisitor& visitor)
+{
+ // Set up iteration range
+ ObjectTree::DepthFirstConstIterator begin(root), end;
+
+ // Invoke generic visitor algorithm
+ ObjectTree::visit(begin, end, visitor);
+}
+
+void dumpTreeFromLeaf(const QObject& leaf, QVisitor& visitor)
+{
+ // Walk up to root
+ const QObject* root = &leaf;
+ while(root->parent())
+ {
+ root = root->parent();
+ }
+
+ dumpTreeFromRoot(*root, visitor);
+}
+
+void dumpAncestors(const QObject& leaf, QVisitor& visitor)
+{
+ // Set up iteration range
+ ObjectTree::AncestorConstIterator begin(leaf), end;
+
+ // Invoke generic visitor algorithm
+ ObjectTree::visit(begin, end, visitor);
+}
+
+
+} // namespace ObjectDump
+
+QT_END_NAMESPACE
+
diff --git a/src/3rdparty/phonon/mmf/objectdump.h b/src/3rdparty/phonon/mmf/objectdump.h
new file mode 100644
index 0000000..86aeaba
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/objectdump.h
@@ -0,0 +1,164 @@
+/* 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 OBJECTDUMP_H
+#define OBJECTDUMP_H
+
+#include <QObject>
+#include <QList>
+#include <QByteArray>
+#include <QScopedPointer>
+
+QT_BEGIN_NAMESPACE
+
+namespace ObjectDump
+{
+
+/**
+ * Abstract base for annotator classes invoked by QVisitor.
+ */
+class QAnnotator : public QObject
+{
+ Q_OBJECT
+public:
+ virtual ~QAnnotator();
+ virtual QList<QByteArray> annotation(const QObject& object) = 0;
+};
+
+/**
+ * Annotator which replicates QObject::dumpObjectTree functionality.
+ */
+class QAnnotatorBasic : public QAnnotator
+{
+ Q_OBJECT
+public:
+ QList<QByteArray> annotation(const QObject& object);
+};
+
+/**
+ * Annotator which returns widget information.
+ */
+class QAnnotatorWidget : public QAnnotator
+{
+ Q_OBJECT
+public:
+ QList<QByteArray> annotation(const QObject& object);
+};
+
+
+class QDumperPrivate;
+
+/**
+ * Class used to dump information about individual QObjects.
+ */
+class QDumper : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QDumper)
+
+public:
+ QDumper();
+ ~QDumper();
+
+ /**
+ * Specify a prefix, to be printed on each line of output.
+ */
+ void setPrefix(const QString& prefix);
+
+ /**
+ * Takes ownership of annotator.
+ */
+ void addAnnotator(QAnnotator* annotator);
+
+ /**
+ * Invoke each annotator on the object and write to debug output.
+ */
+ void dumpObject(const QObject& object);
+
+private:
+ QScopedPointer<QDumperPrivate> d_ptr;
+
+};
+
+
+class QVisitorPrivate;
+
+/**
+ * Visitor class which dumps information about nodes in the object tree.
+ */
+class QVisitor : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QVisitor)
+
+public:
+ QVisitor();
+ ~QVisitor();
+
+ /**
+ * Specify a prefix, to be printed on each line of output.
+ */
+ void setPrefix(const QString& prefix);
+
+ /**
+ * Set number of spaces by which each level of the tree is indented.
+ */
+ void setIndent(unsigned indent);
+
+ /**
+ * Called by the visitor algorithm before starting the visit.
+ */
+ void visitPrepare();
+
+ /**
+ * Called by the visitor algorithm as each node is visited.
+ */
+ void visitNode(const QObject& object);
+
+ /**
+ * Called by the visitor algorithm when the visit is complete.
+ */
+ void visitComplete();
+
+ /**
+ * Takes ownership of annotator.
+ */
+ void addAnnotator(QAnnotator* annotator);
+
+private:
+ QScopedPointer<QVisitorPrivate> d_ptr;
+
+};
+
+
+//-----------------------------------------------------------------------------
+// Utility functions
+//-----------------------------------------------------------------------------
+
+void addDefaultAnnotators(QDumper& dumper);
+void addDefaultAnnotators(QVisitor& visitor);
+
+void dumpTreeFromRoot(const QObject& root, QVisitor& visitor);
+void dumpTreeFromLeaf(const QObject& leaf, QVisitor& visitor);
+void dumpAncestors(const QObject& leaf, QVisitor& visitor);
+
+} // namespace ObjectDump
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/3rdparty/phonon/mmf/objectdump_symbian.cpp b/src/3rdparty/phonon/mmf/objectdump_symbian.cpp
new file mode 100644
index 0000000..edad537
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/objectdump_symbian.cpp
@@ -0,0 +1,160 @@
+/* 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 <QTextStream>
+#include <QWidget>
+#include <coecntrl.h>
+#include "objectdump_symbian.h"
+
+#include <QtGui/private/qwidget_p.h> // to access QWExtra
+
+QT_BEGIN_NAMESPACE
+
+namespace ObjectDump
+{
+namespace Symbian
+{
+
+QList<QByteArray> QAnnotatorWidget::annotation(const QObject& object)
+{
+ QList<QByteArray> result;
+
+ const QWidget* widget = qobject_cast<const QWidget*>(&object);
+ if (widget) {
+
+ const QWExtra* extra = qt_widget_private(const_cast<QWidget *>(widget))->extraData();
+
+ if (extra) {
+
+ QByteArray array;
+ QTextStream stream(&array);
+
+ stream << "widget (Symbian): ";
+ stream << "activated " << extra->activated << ' ';
+ stream << "nativePaintMode " << extra->nativePaintMode << ' ';
+
+ stream.flush();
+ result.append(array);
+ }
+ }
+
+ return result;
+}
+
+QList<QByteArray> QAnnotatorControl::annotation(const QObject& object)
+{
+ QList<QByteArray> result;
+
+ const QWidget* widget = qobject_cast<const QWidget*>(&object);
+ if (widget) {
+
+ const CCoeControl* control = widget->effectiveWinId();
+ if (control) {
+
+ QByteArray array;
+ QTextStream stream(&array);
+
+ stream << "control: " << control << ' ';
+ stream << "parent " << control->Parent() << ' ';
+
+ if (control->IsVisible())
+ stream << "visible ";
+ else
+ stream << "invisible ";
+
+ stream << control->Position().iX << ',' << control->Position().iY << ' ';
+ stream << control->Size().iWidth << 'x' << control->Size().iHeight;
+
+ if (control->OwnsWindow())
+ stream << " ownsWindow ";
+
+ stream.flush();
+ result.append(array);
+ }
+ }
+
+ return result;
+}
+
+QList<QByteArray> QAnnotatorWindow::annotation(const QObject& object)
+{
+ QList<QByteArray> result;
+
+ const QWidget* widget = qobject_cast<const QWidget*>(&object);
+ if (widget) {
+
+ const CCoeControl* control = widget->effectiveWinId();
+
+ if (control) {
+ RDrawableWindow *const window = control->DrawableWindow();
+ if(window) {
+ QByteArray array;
+ QTextStream stream(&array);
+
+ stream << "window: ";
+
+ // Server-side address of CWsWindow object
+ // This is useful for correlation with the window tree dumped by the window
+ // server (see RWsSession::LogCommand).
+ // Cast to a void pointer so that log output is in hexadecimal format.
+ stream << "srv " << reinterpret_cast<const void*>(window->WsHandle()) << ' ';
+
+ stream << "group " << window->WindowGroupId() << ' ';
+
+ // Client-side handle to the parent window.
+ // Cast to a void pointer so that log output is in hexadecimal format.
+ stream << "parent " << reinterpret_cast<const void*>(window->Parent()) << ' ';
+
+ stream << window->Position().iX << ',' << window->Position().iY << ' ';
+ stream << '(' << window->AbsPosition().iX << ',' << window->AbsPosition().iY << ") ";
+ stream << window->Size().iWidth << 'x' << window->Size().iHeight << ' ';
+
+ const TDisplayMode displayMode = window->DisplayMode();
+ stream << "mode " << displayMode << ' ';
+
+ stream << "ord " << window->OrdinalPosition();
+
+ stream.flush();
+ result.append(array);
+ }
+ }
+ }
+
+ return result;
+}
+
+} // namespace Symbian
+
+void addDefaultAnnotators_sys(QDumper& dumper)
+{
+ dumper.addAnnotator(new Symbian::QAnnotatorWidget);
+ dumper.addAnnotator(new Symbian::QAnnotatorControl);
+ dumper.addAnnotator(new Symbian::QAnnotatorWindow);
+}
+
+void addDefaultAnnotators_sys(QVisitor& visitor)
+{
+ visitor.addAnnotator(new Symbian::QAnnotatorWidget);
+ visitor.addAnnotator(new Symbian::QAnnotatorControl);
+ visitor.addAnnotator(new Symbian::QAnnotatorWindow);
+}
+
+} // namespace ObjectDump
+
+QT_END_NAMESPACE
+
diff --git a/src/3rdparty/phonon/mmf/objectdump_symbian.h b/src/3rdparty/phonon/mmf/objectdump_symbian.h
new file mode 100644
index 0000000..563c862
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/objectdump_symbian.h
@@ -0,0 +1,66 @@
+/* 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 OBJECTDUMP_SYMBIAN_H
+#define OBJECTDUMP_SYMBIAN_H
+
+#include "objectdump.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace ObjectDump
+{
+namespace Symbian
+{
+
+/**
+ * Annotator which returns Symbian-specific widget information
+ */
+class QAnnotatorWidget : public QAnnotator
+{
+ Q_OBJECT
+public:
+ QList<QByteArray> annotation(const QObject& object);
+};
+
+/**
+ * Annotator which returns control information
+ */
+class QAnnotatorControl : public QAnnotator
+{
+ Q_OBJECT
+public:
+ QList<QByteArray> annotation(const QObject& object);
+};
+
+/**
+ * Annotator which returns window information
+ */
+class QAnnotatorWindow : public QAnnotator
+{
+ Q_OBJECT
+public:
+ QList<QByteArray> annotation(const QObject& object);
+};
+
+} // namespace Symbian
+} // namespace ObjectDump
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/3rdparty/phonon/mmf/objecttree.cpp b/src/3rdparty/phonon/mmf/objecttree.cpp
new file mode 100644
index 0000000..06b0ced
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/objecttree.cpp
@@ -0,0 +1,100 @@
+/* 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 <QTextStream>
+#include <QWidget>
+#include "objecttree.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace ObjectTree
+{
+
+DepthFirstConstIterator::DepthFirstConstIterator()
+ : m_pointee(0)
+{
+
+}
+
+DepthFirstConstIterator::DepthFirstConstIterator
+ (const QObject& root)
+ : m_pointee(&root)
+{
+
+}
+
+DepthFirstConstIterator&
+ DepthFirstConstIterator::operator++()
+{
+ const QObjectList& children = m_pointee->children();
+
+ if (children.count() == 0) {
+ backtrack();
+ }
+ else {
+ m_history.push(0);
+ m_pointee = children.first();
+ }
+
+ return *this;
+}
+
+void DepthFirstConstIterator::backtrack()
+{
+ if (m_history.count()) {
+ const int index = m_history.top();
+ m_history.pop();
+
+ const QObjectList& siblings = m_pointee->parent()->children();
+ if (siblings.count() > index + 1) {
+ m_history.push(index + 1);
+ m_pointee = siblings[index + 1];
+ }
+ else {
+ m_pointee = m_pointee->parent();
+ backtrack();
+ }
+ }
+ else {
+ // Reached end of search
+ m_pointee = 0;
+ }
+}
+
+
+
+AncestorConstIterator::AncestorConstIterator()
+{
+
+}
+
+AncestorConstIterator::AncestorConstIterator(const QObject& leaf)
+{
+ m_ancestors.push(&leaf);
+ QObject* ancestor = leaf.parent();
+ while(ancestor)
+ {
+ m_ancestors.push(ancestor);
+ ancestor = ancestor->parent();
+ }
+}
+
+} // namespace ObjectTree
+
+QT_END_NAMESPACE
+
diff --git a/src/3rdparty/phonon/mmf/objecttree.h b/src/3rdparty/phonon/mmf/objecttree.h
new file mode 100644
index 0000000..96adb6f
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/objecttree.h
@@ -0,0 +1,115 @@
+/* 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 OBJECTTREE_H
+#define OBJECTTREE_H
+
+#include <QObject>
+#include <QStack>
+
+QT_BEGIN_NAMESPACE
+
+namespace ObjectTree
+{
+
+/**
+ * Depth-first iterator for QObject tree
+ */
+class DepthFirstConstIterator
+{
+public:
+ DepthFirstConstIterator();
+ DepthFirstConstIterator(const QObject& root);
+
+ DepthFirstConstIterator& operator++();
+
+ inline bool operator==(const DepthFirstConstIterator& other) const
+ { return other.m_pointee == m_pointee; }
+
+ inline bool operator!=(const DepthFirstConstIterator& other) const
+ { return other.m_pointee != m_pointee; }
+
+ inline const QObject* operator->() const { return m_pointee; }
+ inline const QObject& operator*() const { return *m_pointee; }
+
+private:
+ void backtrack();
+
+private:
+ const QObject* m_pointee;
+ QStack<int> m_history;
+};
+
+/**
+ * Ancestor iterator for QObject tree
+ */
+class AncestorConstIterator
+{
+public:
+ AncestorConstIterator();
+ AncestorConstIterator(const QObject& root);
+
+ inline AncestorConstIterator& operator++()
+ { m_ancestors.pop(); return *this; }
+
+ inline bool operator==(const AncestorConstIterator& other) const
+ { return other.m_ancestors == m_ancestors; }
+
+ inline bool operator!=(const AncestorConstIterator& other) const
+ { return other.m_ancestors != m_ancestors; }
+
+ inline const QObject* operator->() const { return m_ancestors.top(); }
+ inline const QObject& operator*() const { return *m_ancestors.top(); }
+
+private:
+ QStack<const QObject*> m_ancestors;
+
+};
+
+/**
+ * Generic algorithm for visiting nodes in an object tree. Nodes in the
+ * tree are visited in a const context, therefore they are not modified
+ * by this algorithm.
+ *
+ * Visitor must provide functions with the following signatures:
+ *
+ * Called before visit begins
+ * void visitPrepare()
+ *
+ * Called on each node visited
+ * void visitNode(const QObject& object)
+ *
+ * Called when visit is complete
+ * void visitComplete()
+ */
+template <class Iterator, class Visitor>
+void visit(Iterator begin, Iterator end, Visitor& visitor)
+{
+ visitor.visitPrepare();
+
+ for ( ; begin != end; ++begin)
+ visitor.visitNode(*begin);
+
+ visitor.visitComplete();
+}
+
+} // namespace ObjectTree
+
+QT_END_NAMESPACE
+
+#endif // OBJECTTREE_H
diff --git a/src/3rdparty/phonon/mmf/stereowidening.cpp b/src/3rdparty/phonon/mmf/stereowidening.cpp
new file mode 100644
index 0000000..f90651b
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/stereowidening.cpp
@@ -0,0 +1,93 @@
+/* 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 <StereoWideningBase.h>
+#include "stereowidening.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+// Define functions which depend on concrete native effect class name
+PHONON_MMF_DEFINE_EFFECT_FUNCTIONS(StereoWidening)
+
+/*! \class MMF::StereoWidening
+ \internal
+*/
+
+StereoWidening::StereoWidening(QObject *parent, const QList<EffectParameter>& parameters)
+ : AbstractAudioEffect::AbstractAudioEffect(parent, parameters)
+{
+
+}
+
+int StereoWidening::parameterChanged(const EffectParameter &param,
+ const QVariant &value)
+{
+ Q_ASSERT_X(param.id() == ParameterBase, Q_FUNC_INFO, "Invalid parameter ID");
+
+ const qreal externalLevel = value.toReal();
+ const int internalLevel = param.toInternalValue(externalLevel);
+
+ TRAPD(err, concreteEffect()->SetStereoWideningLevelL(internalLevel));
+
+ return err;
+}
+
+//-----------------------------------------------------------------------------
+// Static functions
+//-----------------------------------------------------------------------------
+
+const char* StereoWidening::description()
+{
+ return "Stereo widening";
+}
+
+bool StereoWidening::getParameters(CMdaAudioOutputStream *stream,
+ QList<EffectParameter> &parameters)
+{
+ bool supported = false;
+
+ QScopedPointer<CStereoWidening> effect;
+ TRAPD(err, effect.reset(CStereoWidening::NewL(*stream)));
+
+ if (KErrNone == err) {
+ supported = true;
+
+ const qreal defaultValue =
+ Phonon::MMF::EffectParameter::toExternalValue
+ (effect->StereoWideningLevel(), 0, 100);
+
+ EffectParameter param(
+ /* parameterId */ ParameterBase,
+ /* name */ tr("Level (%)"),
+ /* hints */ EffectParameter::IntegerHint,
+ /* defaultValue */ QVariant(defaultValue),
+ /* minimumValue */ QVariant(qreal(-1.0)),
+ /* maximumValue */ QVariant(qreal(+1.0)));
+
+ param.setInternalRange(0, 100);
+ parameters.append(param);
+ }
+
+ return supported;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/3rdparty/phonon/mmf/stereowidening.h b/src/3rdparty/phonon/mmf/stereowidening.h
new file mode 100644
index 0000000..c967e37
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/stereowidening.h
@@ -0,0 +1,62 @@
+/* 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_STEREOWIDENING_H
+#define PHONON_MMF_STEREOWIDENING_H
+
+#include "abstractaudioeffect.h"
+
+class CStereoWidening;
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace MMF
+{
+/**
+ * @short A "bass boost" effect.
+ */
+class StereoWidening : public AbstractAudioEffect
+{
+ Q_OBJECT
+public:
+ StereoWidening(QObject *parent, const QList<EffectParameter>& parameters);
+
+ // Static interface required by EffectFactory
+ static const char* description();
+ static bool getParameters(CMdaAudioOutputStream *stream,
+ QList<EffectParameter>& parameters);
+
+protected:
+ // AbstractAudioEffect
+ virtual void createEffect(AudioPlayer::NativePlayer *player);
+ virtual int parameterChanged(const EffectParameter &param,
+ const QVariant &value);
+
+private:
+ CStereoWidening *concreteEffect();
+
+};
+}
+}
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/3rdparty/phonon/mmf/utils.cpp b/src/3rdparty/phonon/mmf/utils.cpp
new file mode 100644
index 0000000..c556afc
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/utils.cpp
@@ -0,0 +1,260 @@
+/* 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 "utils.h"
+#include <e32std.h>
+#include <mmf/common/mmferrors.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+/*! \namespace Phonon::MMF::Utils
+ \internal
+*/
+
+/*! \class Phonon::MMF::TTraceContext
+ \internal
+*/
+
+/*! \enum Phonon::MMF::PanicCode
+ \internal
+*/
+
+/*! \enum Phonon::MMF::TTraceCategory
+ \internal
+*/
+
+/*! \enum Phonon::MMF::MediaType
+ \internal
+*/
+
+_LIT(PanicCategory, "Phonon::MMF");
+
+void MMF::Utils::panic(PanicCode code)
+{
+ User::Panic(PanicCategory, code);
+}
+
+_LIT(KMimePrefixAudio, "audio/");
+_LIT(KMimePrefixVideo, "video/");
+_LIT(KMimeSDP, "application/sdp");
+
+enum ConstantStringLengths {
+ KMimePrefixLength = 6, // either "audio/" or "video/",
+ KMimeSDPLength = 15 // "application/sdp"
+};
+
+MMF::MediaType MMF::Utils::mimeTypeToMediaType(const TDesC& mimeType)
+{
+ if (mimeType.Left(KMimePrefixLength).Compare(KMimePrefixAudio) == 0) {
+ return MediaTypeAudio;
+ } else if (mimeType.Left(KMimePrefixLength).Compare(KMimePrefixVideo) == 0 ||
+ mimeType.Left(KMimeSDPLength).Compare(KMimeSDP) == 0) {
+ return MediaTypeVideo;
+ } else
+ return MediaTypeUnknown;
+}
+
+QString MMF::Utils::symbianErrorToString(int errorCode)
+{
+ /**
+ * Here we translate only the error codes which are likely to be
+ * meaningful to the user. For example, when an error occurs
+ * during opening of a media file, displaying "not found" or
+ * "permission denied" is informative. On the other hand,
+ * differentiating between KErrGeneral and KErrArgument at the UI
+ * level does not make sense.
+ */
+ switch (errorCode)
+ {
+ // System-wide errors
+ case KErrNone:
+ return tr("No error");
+ case KErrNotFound:
+ return tr("Not found");
+ case KErrNoMemory:
+ return tr("Out of memory");
+ case KErrNotSupported:
+ return tr("Not supported");
+ case KErrOverflow:
+ return tr("Overflow");
+ case KErrUnderflow:
+ return tr("Underflow");
+ case KErrAlreadyExists:
+ return tr("Already exists");
+ case KErrPathNotFound:
+ return tr("Path not found");
+ case KErrInUse:
+ return tr("In use");
+ case KErrNotReady:
+ return tr("Not ready");
+ case KErrAccessDenied:
+ return tr("Access denied");
+ case KErrCouldNotConnect:
+ return tr("Could not connect");
+ case KErrDisconnected:
+ return tr("Disconnected");
+ case KErrPermissionDenied:
+ return tr("Permission denied");
+
+ // Multimedia framework errors
+ case KErrMMNotEnoughBandwidth:
+ return tr("Insufficient bandwidth");
+ case KErrMMSocketServiceNotFound:
+ case KErrMMServerSocket:
+ return tr("Network unavailable");
+ case KErrMMNetworkRead:
+ case KErrMMNetworkWrite:
+ case KErrMMUDPReceive:
+ return tr("Network communication error");
+ case KErrMMServerNotSupported:
+ return tr("Streaming not supported");
+ case KErrMMServerAlert:
+ return tr("Server alert");
+ case KErrMMInvalidProtocol:
+ return tr("Invalid protocol");
+ case KErrMMInvalidURL:
+ return tr("Invalid URL");
+ case KErrMMMulticast:
+ return tr("Multicast error");
+ case KErrMMProxyServer:
+ case KErrMMProxyServerConnect:
+ return tr("Proxy server error");
+ case KErrMMProxyServerNotSupported:
+ return tr("Proxy server not supported");
+ case KErrMMAudioDevice:
+ return tr("Audio output error");
+ case KErrMMVideoDevice:
+ return tr("Video output error");
+ case KErrMMDecoder:
+ return tr("Decoder error");
+ case KErrMMPartialPlayback:
+ return tr("Audio or video components could not be played");
+ case KErrMMDRMNotAuthorized:
+ return tr("DRM error");
+
+ /*
+ // We don't use QoS settings
+ case KErrMMQosLowBandwidth:
+ case KErrMMQosUnsupportedTrafficClass:
+ case KErrMMQosPoorTrafficClass:
+ case KErrMMQosUnsupportedParameters:
+ case KErrMMQosPoorParameters:
+ case KErrMMQosNotSupported:
+ */
+
+ // Catch-all for errors other than those above
+ default:
+ {
+ return tr("Unknown error (%1)").arg(errorCode);
+ }
+ }
+}
+
+#ifndef QT_NO_DEBUG
+
+#include <hal.h>
+#include <hal_data.h>
+#include <gdi.h>
+#include <eikenv.h>
+
+struct TScreenInfo
+{
+ int width;
+ int height;
+ int bpp;
+ const char* address;
+ int initialOffset;
+ int lineOffset;
+ TDisplayMode displayMode;
+};
+
+static void getScreenInfoL(TScreenInfo& info)
+{
+ info.displayMode = CEikonEnv::Static()->ScreenDevice()->DisplayMode();
+
+ // Then we must set these as the input parameter
+ info.width = info.displayMode;
+ info.height = info.displayMode;
+ info.initialOffset = info.displayMode;
+ info.lineOffset = info.displayMode;
+ info.bpp = info.displayMode;
+
+ User::LeaveIfError( HAL::Get(HALData::EDisplayXPixels, info.width) );
+ User::LeaveIfError( HAL::Get(HALData::EDisplayYPixels, info.width) );
+
+ int address;
+ User::LeaveIfError( HAL::Get(HALData::EDisplayMemoryAddress, address) );
+ info.address = reinterpret_cast<const char*>(address);
+
+ User::LeaveIfError( HAL::Get(HALData::EDisplayOffsetToFirstPixel, info.initialOffset) );
+
+ User::LeaveIfError( HAL::Get(HALData::EDisplayOffsetBetweenLines, info.lineOffset) );
+
+ User::LeaveIfError( HAL::Get(HALData::EDisplayBitsPerPixel, info.bpp) );
+}
+
+
+QColor MMF::Utils::getScreenPixel(const QPoint& pos)
+{
+ TScreenInfo info;
+ TRAPD(err, getScreenInfoL(info));
+ QColor pixel;
+ if (err == KErrNone and pos.x() < info.width and pos.y() < info.height)
+ {
+ const int bytesPerPixel = info.bpp / 8;
+ Q_ASSERT(bytesPerPixel >= 3);
+
+ const int stride = (info.width * bytesPerPixel) + info.lineOffset;
+
+ const char* ptr =
+ info.address
+ + info.initialOffset
+ + pos.y() * stride
+ + pos.x() * bytesPerPixel;
+
+ // BGRA
+ pixel.setBlue(*ptr++);
+ pixel.setGreen(*ptr++);
+ pixel.setRed(*ptr++);
+
+ if (bytesPerPixel == 4)
+ pixel.setAlpha(*ptr++);
+ }
+ return pixel;
+}
+
+// Debugging: for debugging video visibility
+void MMF::Utils::dumpScreenPixelSample()
+{
+ for (int i=0; i<20; ++i) {
+ const QPoint pos(i*10, i*10);
+ const QColor pixel = Utils::getScreenPixel(pos);
+ RDebug::Printf(
+ "Phonon::MMF::Utils::dumpScreenPixelSample %d %d = %d %d %d %d",
+ pos.x(), pos.y(), pixel.red(), pixel.green(), pixel.blue(), pixel.alpha()
+ );
+ }
+}
+
+#endif // _DEBUG
+
+QT_END_NAMESPACE
+
diff --git a/src/3rdparty/phonon/mmf/utils.h b/src/3rdparty/phonon/mmf/utils.h
new file mode 100644
index 0000000..acad55a
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/utils.h
@@ -0,0 +1,176 @@
+/* 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_UTILS_H
+#define PHONON_MMF_UTILS_H
+
+#include <private/qcore_symbian_p.h>
+#include <e32debug.h> // for RDebug
+#include <QtCore/QCoreApplication> // for Q_DECLARE_TR_FUNCTIONS
+#include <QColor>
+
+#include "defs.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace MMF
+{
+/**
+ * Panic codes for fatal errors
+ */
+enum PanicCode {
+ InvalidStatePanic = 1,
+ InvalidMediaTypePanic = 2,
+ InvalidBackendInterfaceClass = 3,
+ AudioUtilityUrlNotSupported = 4
+};
+
+class Utils
+{
+ Q_DECLARE_TR_FUNCTIONS(Phonon::MMF)
+
+public:
+/**
+ * Raise a fatal exception
+ */
+static void panic(PanicCode code);
+
+/**
+ * Determines whether the provided MIME type is an audio or video
+ * type. If it is neither, the function returns MediaTypeUnknown.
+ */
+static MediaType mimeTypeToMediaType(const TDesC& mimeType);
+
+/**
+ * Translates a Symbian error code into a user-readable string.
+ */
+static QString symbianErrorToString(int errorCode);
+
+#ifndef QT_NO_DEBUG
+/**
+ * Retrieve color of specified pixel from the screen.
+ */
+static QColor getScreenPixel(const QPoint& pos);
+
+/**
+ * Samples a small number of pixels from the screen, and dumps their
+ * colors to the debug log.
+ */
+static void dumpScreenPixelSample();
+#endif
+};
+
+/**
+ * Available trace categories;
+ */
+enum TTraceCategory {
+ /**
+ * Backend
+ */
+ EBackend = 0x00000001,
+
+ /**
+ * Functions which map directly to the public Phonon audio API
+ */
+ EAudioApi = 0x00000010,
+
+ /**
+ * Internal functions in the audio implementation
+ */
+ EAudioInternal = 0x00000020,
+
+ /**
+ * Functions which map directly to the public Phonon video API
+ */
+ EVideoApi = 0x00010000,
+
+ /**
+ * Internal functions in the video implementation
+ */
+ EVideoInternal = 0x00020000
+};
+
+/**
+ * Mask indicating which trace categories are enabled
+ *
+ * Note that, at the moment, this is a compiled static constant. For
+ * runtime control over enabled trace categories, this could be replaced
+ * by a per-thread singleton object which owns the trace mask, and which
+ * exposes an API allowing it to be modified.
+ */
+static const TUint KTraceMask = 0xffffffff;
+
+/**
+ * Data structure used by tracing macros
+ */
+class TTraceContext
+{
+public:
+ TTraceContext(const TText* aFunction, const TUint aAddr,
+ const TUint aCategory = 0)
+ : iFunction(aFunction),
+ iAddr(aAddr),
+ iCategory(aCategory) { }
+
+ /**
+ * Check whether iCategory appears in the trace mask
+ */
+ TBool Enabled() const {
+ return (iCategory == 0) or(iCategory & KTraceMask);
+ }
+
+ const TText* iFunction; // Name of function
+ const TUint iAddr; // 'this' pointer
+ const TUint iCategory;
+};
+
+// Macros used internally by the trace system
+#define _TRACE_PRINT RDebug::Print
+#define _TRACE_TEXT(x) (TPtrC((const TText *)(x)))
+#define _TRACE_MODULE Phonon::MMF
+
+// Macros available for use by implementation code
+#ifndef QT_NO_DEBUG
+#define TRACE_CONTEXT(_fn, _cat) const ::Phonon::MMF::TTraceContext _tc((TText*)L ## #_fn, (TUint)this, _cat);
+#define TRACE_ENTRY_0() { if (_tc.Enabled()) _TRACE_PRINT(_TRACE_TEXT(L ## "+ Phonon::MMF::%s [0x%08x]"), _tc.iFunction, _tc.iAddr); }
+#define TRACE_ENTRY(string, args...) { if (_tc.Enabled()) _TRACE_PRINT(_TRACE_TEXT(L ## "+ Phonon::MMF::%s [0x%08x] " L ## string), _tc.iFunction, _tc.iAddr, args); }
+#define TRACE_EXIT_0() { if (_tc.Enabled()) _TRACE_PRINT(_TRACE_TEXT(L ## "- Phonon::MMF::%s [0x%08x]"), _tc.iFunction, _tc.iAddr); }
+#define TRACE_EXIT(string, args...) { if (_tc.Enabled()) _TRACE_PRINT(_TRACE_TEXT(L ## "- Phonon::MMF::%s [0x%08x] " L ## string), _tc.iFunction, _tc.iAddr, args); }
+#define TRACE_RETURN(string, result) { if (_tc.Enabled()) _TRACE_PRINT(_TRACE_TEXT(L ## "r Phonon::MMF::%s [0x%08x] " L ## string), _tc.iFunction, _tc.iAddr, result); } return result;
+#define TRACE_PANIC(code) { _TRACE_PRINT(_TRACE_TEXT(L ## "! Phonon::MMF::%s [0x%08x] panic %d"), _tc.iFunction, _tc.iAddr, code); } Utils::panic(code);
+#define TRACE_0(string) { if (_tc.Enabled()) _TRACE_PRINT(_TRACE_TEXT(L ## " Phonon::MMF::%s [0x%08x] " L ## string), _tc.iFunction, _tc.iAddr); }
+#define TRACE(string, args...) { if (_tc.Enabled()) _TRACE_PRINT(_TRACE_TEXT(L ## " Phonon::MMF::%s [0x%08x] " L ## string), _tc.iFunction, _tc.iAddr, args); }
+#else
+#define TRACE_CONTEXT(_fn, _cat)
+#define TRACE_ENTRY_0()
+#define TRACE_ENTRY(string, args...)
+#define TRACE_EXIT_0()
+#define TRACE_EXIT(string, args...)
+#define TRACE_RETURN(string, result) return result;
+#define TRACE_PANIC(code) Utils::panic(code);
+#define TRACE_0(string)
+#define TRACE(string, args...)
+#endif
+}
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/3rdparty/phonon/mmf/videooutput_dsa.cpp b/src/3rdparty/phonon/mmf/videooutput_dsa.cpp
new file mode 100644
index 0000000..4f9ad7f
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/videooutput_dsa.cpp
@@ -0,0 +1,183 @@
+/* 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 <QtCore/private/qcore_symbian_p.h> // for qt_TRect2QRect
+#include <QtGui/private/qwidget_p.h> // to access QWExtra
+#include <QResizeEvent>
+#include <QMoveEvent>
+
+#include <coemain.h> // for CCoeEnv
+
+#include "ancestormovemonitor.h"
+#include "utils.h"
+#include "videooutput_dsa.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+DsaVideoOutput::DsaVideoOutput(QWidget *parent)
+ : AbstractVideoOutput(parent)
+ , m_ancestorMoveMonitor(0)
+{
+ TRACE_CONTEXT(DsaVideoOutput::DsaVideoOutput, EVideoInternal);
+ TRACE_ENTRY("parent 0x%08x", parent);
+
+ setPalette(QPalette(Qt::black));
+ setAttribute(Qt::WA_OpaquePaintEvent, true);
+ setAttribute(Qt::WA_NoSystemBackground, true);
+ setAutoFillBackground(false);
+
+ qt_widget_private(this)->extraData()->nativePaintMode = QWExtra::ZeroFill;
+ qt_widget_private(this)->extraData()->receiveNativePaintEvents = true;
+
+ getVideoWindowScreenRect();
+
+ dump();
+
+ TRACE_EXIT_0();
+}
+
+DsaVideoOutput::~DsaVideoOutput()
+{
+ TRACE_CONTEXT(DsaVideoOutput::~DsaVideoOutput, EVideoInternal);
+ TRACE_ENTRY_0();
+
+ m_ancestorMoveMonitor->unRegisterTarget(this);
+
+ TRACE_EXIT_0();
+}
+
+//-----------------------------------------------------------------------------
+// Public functions
+//-----------------------------------------------------------------------------
+
+void MMF::DsaVideoOutput::setAncestorMoveMonitor(AncestorMoveMonitor *monitor)
+{
+ m_ancestorMoveMonitor = monitor;
+ registerForAncestorMoved();
+}
+
+const QRect& MMF::DsaVideoOutput::videoWindowScreenRect() const
+{
+ return m_videoWindowScreenRect;
+}
+
+void MMF::DsaVideoOutput::ancestorMoved()
+{
+ TRACE_CONTEXT(DsaVideoOutput::ancestorMoved, EVideoInternal);
+ TRACE_ENTRY_0();
+
+ RWindowBase *const window = videoWindow();
+
+ if (window) {
+ const TPoint newWindowPosSymbian = window->AbsPosition();
+ const QPoint newWindowPos(newWindowPosSymbian.iX, newWindowPosSymbian.iY);
+
+ if (newWindowPos != m_videoWindowScreenRect.topLeft()) {
+ m_videoWindowScreenRect.moveTo(newWindowPos);
+ emit videoWindowScreenRectChanged();
+ }
+ }
+
+ TRACE_EXIT_0();
+}
+
+void MMF::DsaVideoOutput::beginNativePaintEvent(const QRect & /*controlRect*/)
+{
+ TRACE_CONTEXT(DsaVideoOutput::beginNativePaintEvent, EVideoInternal);
+ TRACE_ENTRY_0();
+
+ emit beginVideoWindowNativePaint();
+}
+
+void MMF::DsaVideoOutput::endNativePaintEvent(const QRect & /*controlRect*/)
+{
+ TRACE_CONTEXT(DsaVideoOutput::endNativePaintEvent, EVideoInternal);
+ TRACE_ENTRY_0();
+
+ // Ensure that draw ops are executed into the WSERV output framebuffer
+ CCoeEnv::Static()->WsSession().Flush();
+
+ emit endVideoWindowNativePaint();
+}
+
+//-----------------------------------------------------------------------------
+// Private functions
+//-----------------------------------------------------------------------------
+
+void MMF::DsaVideoOutput::getVideoWindowScreenRect()
+{
+ RWindowBase *const window = videoWindow();
+ if (window)
+ m_videoWindowScreenRect =
+ qt_TRect2QRect(TRect(window->AbsPosition(), window->Size()));
+}
+
+void MMF::DsaVideoOutput::registerForAncestorMoved()
+{
+ m_ancestorMoveMonitor->registerTarget(this);
+}
+
+void MMF::DsaVideoOutput::resizeEvent(QResizeEvent *event)
+{
+ TRACE_CONTEXT(DsaVideoOutput::resizeEvent, EVideoInternal);
+ TRACE("%d %d -> %d %d",
+ event->oldSize().width(), event->oldSize().height(),
+ event->size().width(), event->size().height());
+
+ if (event->size() != event->oldSize()) {
+ m_videoWindowScreenRect.setSize(event->size());
+ emit videoWindowScreenRectChanged();
+ }
+}
+
+void MMF::DsaVideoOutput::moveEvent(QMoveEvent *event)
+{
+ TRACE_CONTEXT(DsaVideoOutput::moveEvent, EVideoInternal);
+ TRACE("%d %d -> %d %d",
+ event->oldPos().x(), event->oldPos().y(),
+ event->pos().x(), event->pos().y());
+
+ if (event->pos() != event->oldPos()) {
+ m_videoWindowScreenRect.moveTo(event->pos());
+ emit videoWindowScreenRectChanged();
+ }
+}
+
+bool MMF::DsaVideoOutput::event(QEvent *event)
+{
+ TRACE_CONTEXT(DsaVideoOutput::event, EVideoInternal);
+
+ if (event->type() == QEvent::WinIdChange) {
+ TRACE_0("WinIdChange");
+ getVideoWindowScreenRect();
+ emit videoWindowChanged();
+ return true;
+ } 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);
+ }
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/3rdparty/phonon/mmf/videooutput_dsa.h b/src/3rdparty/phonon/mmf/videooutput_dsa.h
new file mode 100644
index 0000000..c37dad8
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/videooutput_dsa.h
@@ -0,0 +1,109 @@
+/* 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_VIDEOOUTPUT_DSA_H
+#define PHONON_MMF_VIDEOOUTPUT_DSA_H
+
+#include <QRect>
+
+#include "phonon/mmf/abstractvideooutput.h"
+
+QT_BEGIN_NAMESPACE
+
+class QResizeEvent;
+class QMoveEvent;
+
+namespace Phonon
+{
+namespace MMF
+{
+class AncestorMoveMonitor;
+
+/**
+ * @short Widget on which video is displayed by DSA rendering
+ *
+ * This implementation is used on devices with the legacy graphics
+ * subsystem, which does not support surfaces. On such devices,
+ * video rendering is done via Direct Screen Access (DSA), whereby
+ * the video decoder writes directly to the framebuffer. To ensure
+ * that the window server and video decoder do not try to draw to
+ * the same screen region at the same time, the video subsystem
+ * first requests permission to perform DSA. If the window server
+ * needs to draw to this screen region (for example to display a
+ * message dialog), it first notifies the video subsystem that it
+ * must stop rendering to this region.
+ *
+ * @see SurfaceVideoOutput
+ */
+class DsaVideoOutput
+ : public AbstractVideoOutput
+{
+ Q_OBJECT
+
+public:
+ DsaVideoOutput(QWidget *parent);
+ ~DsaVideoOutput();
+
+ void setAncestorMoveMonitor(AncestorMoveMonitor *monitor);
+
+ // Get absolute screen rectangle for video window
+ const QRect& videoWindowScreenRect() const;
+
+ // Called by AncestorMoveMonitor
+ void ancestorMoved();
+
+public Q_SLOTS:
+ // Callbacks received from Symbian QtGui implementation, when it
+ // begins / ends blitting the video widget's backing store to the
+ // window server.
+ void beginNativePaintEvent(const QRect & /*controlRect*/);
+ void endNativePaintEvent(const QRect & /*controlRect*/);
+
+Q_SIGNALS:
+ void videoWindowScreenRectChanged();
+
+ // Emitted when the Symbian QtGui implementation begins / ends
+ // blitting the video widget's backing store to the window server.
+ void beginVideoWindowNativePaint();
+ void endVideoWindowNativePaint();
+
+private:
+ void getVideoWindowScreenRect();
+ void registerForAncestorMoved();
+
+ // QWidget
+ void resizeEvent(QResizeEvent *event);
+ void moveEvent(QMoveEvent *event);
+ bool event(QEvent *event);
+
+private:
+ // Not owned
+ AncestorMoveMonitor* m_ancestorMoveMonitor;
+
+ // Absolute screen rectangle on which video is displayed
+ QRect m_videoWindowScreenRect;
+
+};
+
+}
+}
+
+QT_END_NAMESPACE
+
+#endif // !PHONON_MMF_VIDEOOUTPUT_DSA_H
+
diff --git a/src/3rdparty/phonon/mmf/videooutput_surface.cpp b/src/3rdparty/phonon/mmf/videooutput_surface.cpp
new file mode 100644
index 0000000..e9b2d3f
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/videooutput_surface.cpp
@@ -0,0 +1,87 @@
+/* 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 <QResizeEvent>
+
+#include <QtCore/private/qcore_symbian_p.h> // for qt_TRect2QRect
+#include <QtGui/private/qwidget_p.h> // to access QWExtra
+
+#include "utils.h"
+#include "videooutput_surface.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+SurfaceVideoOutput::SurfaceVideoOutput(QWidget *parent)
+ : AbstractVideoOutput(parent)
+{
+ TRACE_CONTEXT(SurfaceVideoOutput::SurfaceVideoOutput, EVideoInternal);
+ TRACE_ENTRY("parent 0x%08x", parent);
+
+ qt_widget_private(this)->createExtra();
+ qt_widget_private(this)->extraData()->nativePaintMode = QWExtra::Disable;
+
+ TRACE_EXIT_0();
+}
+
+SurfaceVideoOutput::~SurfaceVideoOutput()
+{
+ TRACE_CONTEXT(SurfaceVideoOutput::~SurfaceVideoOutput, EVideoInternal);
+ TRACE_ENTRY_0();
+
+ TRACE_EXIT_0();
+}
+
+//-----------------------------------------------------------------------------
+// Public functions
+//-----------------------------------------------------------------------------
+
+
+//-----------------------------------------------------------------------------
+// Private functions
+//-----------------------------------------------------------------------------
+
+void MMF::SurfaceVideoOutput::resizeEvent(QResizeEvent *event)
+{
+ TRACE_CONTEXT(SurfaceVideoOutput::resizeEvent, EVideoInternal);
+ TRACE("%d %d -> %d %d",
+ event->oldSize().width(), event->oldSize().height(),
+ event->size().width(), event->size().height());
+
+ if (event->size() != event->oldSize())
+ emit videoWindowSizeChanged();
+}
+
+bool MMF::SurfaceVideoOutput::event(QEvent *event)
+{
+ TRACE_CONTEXT(SurfaceVideoOutput::event, EVideoInternal);
+
+ if (event->type() == QEvent::WinIdChange) {
+ TRACE_0("WinIdChange");
+ emit videoWindowChanged();
+ return true;
+ } else {
+ return QWidget::event(event);
+ }
+}
+
+
+QT_END_NAMESPACE
+
diff --git a/src/3rdparty/phonon/mmf/videooutput_surface.h b/src/3rdparty/phonon/mmf/videooutput_surface.h
new file mode 100644
index 0000000..0b22a71
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/videooutput_surface.h
@@ -0,0 +1,66 @@
+/* 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_VIDEOOUTPUT_SURFACE_H
+#define PHONON_MMF_VIDEOOUTPUT_SURFACE_H
+
+#include "phonon/mmf/abstractvideooutput.h"
+
+QT_BEGIN_NAMESPACE
+
+class QResizeEvent;
+
+namespace Phonon
+{
+namespace MMF
+{
+
+/**
+ * @short Widget on which video is displayed by rendering to a surface
+ *
+ * This implementation is used on devices with a graphics subsystem which
+ * supports surfaces.
+ *
+ * @see DsaVideoOutput
+ */
+class SurfaceVideoOutput
+ : public AbstractVideoOutput
+{
+ Q_OBJECT
+
+public:
+ SurfaceVideoOutput(QWidget *parent);
+ ~SurfaceVideoOutput();
+
+Q_SIGNALS:
+ void videoWindowSizeChanged();
+
+private:
+ // QWidget
+ void resizeEvent(QResizeEvent *event);
+ bool event(QEvent *event);
+
+};
+
+}
+}
+
+QT_END_NAMESPACE
+
+#endif // !PHONON_MMF_VIDEOOUTPUT_SURFACE_H
+
diff --git a/src/3rdparty/phonon/mmf/videoplayer_dsa.cpp b/src/3rdparty/phonon/mmf/videoplayer_dsa.cpp
new file mode 100644
index 0000000..deb9774
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/videoplayer_dsa.cpp
@@ -0,0 +1,317 @@
+/* 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 <coecntrl.h> // for CCoeControl
+
+#include <QApplication> // for QApplication::activeWindow
+#include <QtCore/private/qcore_symbian_p.h> // for qt_TRect2QRect
+
+#include "utils.h"
+#include "videooutput_dsa.h"
+#include "videoplayer_dsa.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+// Two-phase constructor idiom is used because construct() calls virtual
+// functions and therefore cannot be called from the AbstractVideoPlayer
+// C++ constructor.
+DsaVideoPlayer* DsaVideoPlayer::create(MediaObject *parent,
+ const AbstractPlayer *player)
+{
+ QScopedPointer<DsaVideoPlayer> self(new DsaVideoPlayer(parent, player));
+ self->construct();
+ return self.take();
+}
+
+DsaVideoPlayer::DsaVideoPlayer(MediaObject *parent, const AbstractPlayer *player)
+ : AbstractVideoPlayer(parent, player)
+ , m_dsaActive(false)
+ , m_dsaWasActive(false)
+{
+
+}
+
+DsaVideoPlayer::~DsaVideoPlayer()
+{
+
+}
+
+
+//-----------------------------------------------------------------------------
+// Public functions
+//-----------------------------------------------------------------------------
+
+void MMF::DsaVideoPlayer::videoWindowScreenRectChanged()
+{
+ Q_ASSERT(m_videoOutput);
+
+ QRect windowRect = static_cast<DsaVideoOutput *>(m_videoOutput)->videoWindowScreenRect();
+
+ // Clip to physical window size
+ // This is due to a defect in the layout when running on S60 3.2, which
+ // results in the rectangle of the video widget extending outside the
+ // screen in certain circumstances. These include the initial startup
+ // of the mediaplayer demo in portrait mode. When this rectangle is
+ // passed to the CVideoPlayerUtility, no video is rendered.
+ const TSize screenSize = m_screenDevice.SizeInPixels();
+ const QRect screenRect(0, 0, screenSize.iWidth, screenSize.iHeight);
+ windowRect = windowRect.intersected(screenRect);
+
+ // Recalculate scale factors. Pass 'false' as second parameter in order to
+ // suppress application of the change to the player - this is done at the end
+ // of the function.
+ updateScaleFactors(windowRect.size(), false);
+
+ m_videoScreenRect = qt_QRect2TRect(windowRect);
+
+ parametersChanged(WindowScreenRect | ScaleFactors);
+}
+
+void MMF::DsaVideoPlayer::suspendDirectScreenAccess()
+{
+ m_dsaWasActive = stopDirectScreenAccess();
+}
+
+void MMF::DsaVideoPlayer::resumeDirectScreenAccess()
+{
+ if (m_dsaWasActive) {
+ startDirectScreenAccess();
+ m_dsaWasActive = false;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Private functions
+//-----------------------------------------------------------------------------
+
+void MMF::DsaVideoPlayer::createPlayer()
+{
+ // A window handle must be provided in order to construct
+ // CVideoPlayerUtility. If no VideoOutput has yet been connected to this
+ // player, we temporarily use the top-level application window handle.
+ // No video ever gets rendered into this window; SetDisplayWindowL is
+ // always called before rendering actually begins.
+ if (!m_window)
+ m_window = QApplication::activeWindow()->effectiveWinId()->DrawableWindow();
+
+ const TInt priority = 0;
+ const TMdaPriorityPreference preference = EMdaPriorityPreferenceNone;
+
+ CVideoPlayerUtility *player = 0;
+ QT_TRAP_THROWING(player = CVideoPlayerUtility::NewL(*this,
+ priority, preference,
+ m_wsSession, m_screenDevice,
+ *m_window,
+ m_videoScreenRect, m_videoScreenRect));
+ m_player.reset(player);
+
+ // CVideoPlayerUtility::NewL starts DSA
+ m_dsaActive = true;
+}
+
+void MMF::DsaVideoPlayer::initVideoOutput()
+{
+ Q_ASSERT(m_videoOutput);
+
+ bool connected = connect(
+ m_videoOutput, SIGNAL(videoWindowScreenRectChanged()),
+ this, SLOT(videoWindowScreenRectChanged())
+ );
+ Q_ASSERT(connected);
+
+ connected = connect(
+ m_videoOutput, SIGNAL(beginVideoWindowNativePaint()),
+ this, SLOT(suspendDirectScreenAccess())
+ );
+ Q_ASSERT(connected);
+
+ connected = connect(
+ m_videoOutput, SIGNAL(endVideoWindowNativePaint()),
+ this, SLOT(resumeDirectScreenAccess())
+ );
+ Q_ASSERT(connected);
+
+ // Suppress warnings in release builds
+ Q_UNUSED(connected);
+
+ AbstractVideoPlayer::initVideoOutput();
+}
+
+void MMF::DsaVideoPlayer::prepareCompleted()
+{
+ if (m_videoOutput)
+ videoWindowScreenRectChanged();
+}
+
+void MMF::DsaVideoPlayer::handleVideoWindowChanged()
+{
+ if (!m_window) {
+ if (QWidget *window = QApplication::activeWindow())
+ m_window = window->effectiveWinId()->DrawableWindow();
+ else
+ m_window = 0;
+ m_videoScreenRect = TRect();
+ }
+
+ parametersChanged(WindowHandle | WindowScreenRect);
+}
+
+#ifndef QT_NO_DEBUG
+
+// The following code is for debugging problems related to video visibility. It allows
+// the VideoPlayer instance to query the window server in order to determine the
+// DSA drawing region for the video window.
+
+class CDummyAO : public CActive
+{
+public:
+ CDummyAO() : CActive(CActive::EPriorityStandard) { CActiveScheduler::Add(this); }
+ void RunL() { }
+ void DoCancel() { }
+ TRequestStatus& Status() { return iStatus; }
+ void SetActive() { CActive::SetActive(); }
+};
+
+void getDsaRegion(RWsSession &session, const RWindowBase &window)
+{
+ // Dump complete window tree
+ session.LogCommand(RWsSession::ELoggingStatusDump);
+
+ RDirectScreenAccess dsa(session);
+ TInt err = dsa.Construct();
+ CDummyAO ao;
+ RRegion* region;
+ err = dsa.Request(region, ao.Status(), window);
+ ao.SetActive();
+ dsa.Close();
+ ao.Cancel();
+ if (region) {
+ qDebug() << "Phonon::MMF::getDsaRegion count" << region->Count();
+ for (int i=0; i<region->Count(); ++i) {
+ const TRect& rect = region->RectangleList()[i];
+ qDebug() << "Phonon::MMF::getDsaRegion rect"
+ << rect.iTl.iX << rect.iTl.iY << rect.iBr.iX << rect.iBr.iY;
+ }
+ region->Close();
+ }
+}
+
+#endif // QT_NO_DEBUG
+
+void MMF::DsaVideoPlayer::handleParametersChanged(VideoParameters parameters)
+{
+ TRACE_CONTEXT(DsaVideoPlayer::handleParametersChanged, EVideoInternal);
+ TRACE_ENTRY("parameters 0x%x", parameters.operator int());
+
+ if (!m_window)
+ return;
+
+#ifndef QT_NO_DEBUG
+ getDsaRegion(m_wsSession, *m_window);
+#endif
+
+ if (m_player) {
+ static const TBool antialias = ETrue;
+ int err = KErrNone;
+
+ if (parameters & ScaleFactors) {
+ TRAP(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight,
+ antialias));
+ if(KErrNone != err) {
+ TRACE("SetScaleFactorL (1) err %d", err);
+ setError(tr("Video display error"), err);
+ }
+ }
+
+ if (KErrNone == err) {
+ if (parameters & WindowHandle || parameters & WindowScreenRect) {
+ TRAP(err,
+ m_player->SetDisplayWindowL(m_wsSession, m_screenDevice,
+ *m_window,
+ m_videoScreenRect,
+ m_videoScreenRect));
+ }
+
+ if (KErrNone != err) {
+ TRACE("SetDisplayWindowL err %d", err);
+ setError(tr("Video display error"), err);
+ } else {
+ m_dsaActive = true;
+ if (parameters & ScaleFactors) {
+ TRAP(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight,
+ antialias));
+ if (KErrNone != err) {
+ TRACE("SetScaleFactorL (2) err %d", err);
+ setError(tr("Video display error"), err);
+ }
+ }
+ }
+ }
+ }
+
+ TRACE_EXIT_0();
+}
+
+void MMF::DsaVideoPlayer::startDirectScreenAccess()
+{
+ TRACE_CONTEXT(DsaVideoPlayer::startDirectScreenAccess, EVideoInternal);
+ TRACE_ENTRY("dsaActive %d", m_dsaActive);
+
+ int err = KErrNone;
+
+ if (!m_dsaActive) {
+ TRAP(err, m_player->StartDirectScreenAccessL());
+ if (KErrNone == err)
+ m_dsaActive = true;
+ else
+ setError(tr("Video display error"), err);
+ }
+
+ if (m_videoOutput)
+ m_videoOutput->dump();
+
+ TRACE_EXIT("error %d", err);
+}
+
+bool MMF::DsaVideoPlayer::stopDirectScreenAccess()
+{
+ TRACE_CONTEXT(DsaVideoPlayer::stopDirectScreenAccess, EVideoInternal);
+ TRACE_ENTRY("dsaActive %d", m_dsaActive);
+
+ int err = KErrNone;
+
+ const bool dsaWasActive = m_dsaActive;
+ if (m_dsaActive) {
+ TRAP(err, m_player->StopDirectScreenAccessL());
+ if (KErrNone == err)
+ m_dsaActive = false;
+ else
+ setError(tr("Video display error"), err);
+ }
+
+ TRACE_EXIT("error %d", err);
+
+ return dsaWasActive;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/3rdparty/phonon/mmf/videoplayer_dsa.h b/src/3rdparty/phonon/mmf/videoplayer_dsa.h
new file mode 100644
index 0000000..45cc47d
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/videoplayer_dsa.h
@@ -0,0 +1,92 @@
+/* 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_VIDEOPLAYER_DSA_H
+#define PHONON_MMF_VIDEOPLAYER_DSA_H
+
+#include "abstractvideoplayer.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace MMF
+{
+
+/**
+ * @short Wrapper over the MMF video player utility (DSA version)
+ *
+ * This implementation is used on devices with the legacy graphics
+ * subsystem, which does not support surfaces. On such devices,
+ * video rendering is done via Direct Screen Access (DSA), whereby
+ * the video decoder writes directly to the framebuffer. To ensure
+ * that the window server and video decoder do not try to draw to
+ * the same screen region at the same time, the video subsystem
+ * first requests permission to perform DSA. If the window server
+ * needs to draw to this screen region (for example to display a
+ * message dialog), it first notifies the video subsystem that it
+ * must stop rendering to this region.
+ *
+ * @see SurfaceVideoPlayer
+ */
+class DsaVideoPlayer
+ : public AbstractVideoPlayer
+{
+ Q_OBJECT
+
+public:
+ // Factory function
+ static DsaVideoPlayer* create(MediaObject *parent = 0,
+ const AbstractPlayer *player = 0);
+ ~DsaVideoPlayer();
+
+public Q_SLOTS:
+ void videoWindowScreenRectChanged();
+ void suspendDirectScreenAccess();
+ void resumeDirectScreenAccess();
+
+private:
+ DsaVideoPlayer(MediaObject *parent, const AbstractPlayer *player);
+
+ // AbstractVideoPlayer
+ void createPlayer();
+ void initVideoOutput();
+ void prepareCompleted();
+ void handleVideoWindowChanged();
+ void handleParametersChanged(VideoParameters parameters);
+
+ void startDirectScreenAccess();
+ bool stopDirectScreenAccess();
+
+private:
+ bool m_dsaActive;
+ bool m_dsaWasActive;
+
+ // Absolute screen rectangle on which video is displayed
+ TRect m_videoScreenRect;
+
+};
+
+}
+}
+
+QT_END_NAMESPACE
+
+#endif // !PHONON_MMF_VIDEOPLAYER_DSA_H
+
+
diff --git a/src/3rdparty/phonon/mmf/videoplayer_surface.cpp b/src/3rdparty/phonon/mmf/videoplayer_surface.cpp
new file mode 100644
index 0000000..f380e69
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/videoplayer_surface.cpp
@@ -0,0 +1,185 @@
+/* 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 <videoplayer2.h>
+
+#include <QtCore/private/qcore_symbian_p.h> // for qt_QRect2TRect
+
+#include "utils.h"
+#include "videooutput_surface.h"
+#include "videoplayer_surface.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+// Two-phase constructor idiom is used because construct() calls virtual
+// functions and therefore cannot be called from the AbstractVideoPlayer
+// C++ constructor.
+SurfaceVideoPlayer* SurfaceVideoPlayer::create(MediaObject *parent,
+ const AbstractPlayer *player)
+{
+ QScopedPointer<SurfaceVideoPlayer> self(new SurfaceVideoPlayer(parent, player));
+ self->construct();
+ return self.take();
+}
+
+SurfaceVideoPlayer::SurfaceVideoPlayer(MediaObject *parent, const AbstractPlayer *player)
+ : AbstractVideoPlayer(parent, player)
+ , m_displayWindow(0)
+{
+
+}
+
+SurfaceVideoPlayer::~SurfaceVideoPlayer()
+{
+
+}
+
+
+//-----------------------------------------------------------------------------
+// Public functions
+//-----------------------------------------------------------------------------
+
+void MMF::SurfaceVideoPlayer::videoWindowSizeChanged()
+{
+ if (m_videoOutput)
+ updateScaleFactors(m_videoOutput->videoWindowSize());
+}
+
+
+//-----------------------------------------------------------------------------
+// Private functions
+//-----------------------------------------------------------------------------
+
+void MMF::SurfaceVideoPlayer::createPlayer()
+{
+ const TInt priority = 0;
+ const TMdaPriorityPreference preference = EMdaPriorityPreferenceNone;
+
+ CVideoPlayerUtility2 *player = 0;
+ QT_TRAP_THROWING(player = CVideoPlayerUtility2::NewL(*this,
+ priority, preference));
+ m_player.reset(player);
+}
+
+void MMF::SurfaceVideoPlayer::initVideoOutput()
+{
+ Q_ASSERT(m_videoOutput);
+
+ bool connected = connect(
+ m_videoOutput, SIGNAL(videoWindowSizeChanged()),
+ this, SLOT(videoWindowSizeChanged())
+ );
+ Q_ASSERT(connected);
+
+ // Suppress warnings in release builds
+ Q_UNUSED(connected);
+
+ AbstractVideoPlayer::initVideoOutput();
+}
+
+void MMF::SurfaceVideoPlayer::prepareCompleted()
+{
+ videoWindowSizeChanged();
+}
+
+void MMF::SurfaceVideoPlayer::handleVideoWindowChanged()
+{
+ parametersChanged(WindowHandle);
+}
+
+void MMF::SurfaceVideoPlayer::handleParametersChanged(VideoParameters parameters)
+{
+ TRACE_CONTEXT(SurfaceVideoPlayer::handleParametersChanged, EVideoApi);
+ TRACE_ENTRY("parameters 0x%x", parameters.operator int());
+
+ TRect rect;
+ if (m_videoOutput) {
+ m_videoOutput->dump();
+ const QSize size = m_videoOutput->videoWindowSize();
+ rect.SetSize(TSize(size.width(), size.height()));
+ }
+
+ CVideoPlayerUtility2 *player = static_cast<CVideoPlayerUtility2 *>(m_player.data());
+ if (player) {
+ int err = KErrNone;
+ if (parameters & WindowHandle) {
+ removeDisplayWindow();
+ addDisplayWindow(rect);
+ }
+
+ if (KErrNone == err) {
+ if (parameters & ScaleFactors) {
+ if (!m_displayWindow)
+ addDisplayWindow(rect);
+ Q_ASSERT(m_displayWindow);
+ TRAP(err, player->SetVideoExtentL(*m_displayWindow, rect));
+ if (KErrNone == err)
+ TRAP(err, player->SetWindowClipRectL(*m_displayWindow, rect));
+ if (KErrNone == err)
+ TRAP(err, player->SetScaleFactorL(*m_displayWindow, m_scaleWidth, m_scaleHeight));
+ if (KErrNone != err)
+ setError(tr("Video display error"), err);
+ }
+ }
+ }
+
+ TRACE_EXIT_0();
+}
+
+void MMF::SurfaceVideoPlayer::addDisplayWindow(const TRect &rect)
+{
+ TRACE_CONTEXT(SurfaceVideoPlayer::addDisplayWindow, EVideoApi);
+ TRACE_ENTRY("rect %d %d - %d %d", rect.iTl.iX, rect.iTl.iY, rect.iBr.iX, rect.iBr.iY);
+
+ Q_ASSERT(!m_displayWindow);
+ RWindow *window = static_cast<RWindow *>(m_window);
+
+ TRACE("window 0x%08x", window);
+
+ if (window) {
+ window->SetBackgroundColor(TRgb(0, 0, 0, 255));
+ CVideoPlayerUtility2 *player = static_cast<CVideoPlayerUtility2 *>(m_player.data());
+ Q_ASSERT(player);
+ TRAPD(err, player->AddDisplayWindowL(m_wsSession, m_screenDevice, *window, rect, rect));
+ if (KErrNone == err)
+ m_displayWindow = window;
+ else
+ setError(tr("Video display error"), err);
+ TRACE("err %d", err);
+ }
+
+ TRACE_EXIT_0();
+}
+
+void MMF::SurfaceVideoPlayer::removeDisplayWindow()
+{
+ TRACE_CONTEXT(SurfaceVideoPlayer::removeDisplayWindow, EVideoApi);
+ TRACE("player 0x%08x window 0x%08x", m_player.data(), m_displayWindow);
+
+ CVideoPlayerUtility2 *player = static_cast<CVideoPlayerUtility2 *>(m_player.data());
+ if (player && m_displayWindow) {
+ player->RemoveDisplayWindow(*m_displayWindow);
+ m_displayWindow = 0;
+ }
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/3rdparty/phonon/mmf/videoplayer_surface.h b/src/3rdparty/phonon/mmf/videoplayer_surface.h
new file mode 100644
index 0000000..8572fdc
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/videoplayer_surface.h
@@ -0,0 +1,81 @@
+/* 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_VIDEOPLAYER_SURFACE_H
+#define PHONON_MMF_VIDEOPLAYER_SURFACE_H
+
+#include "abstractvideoplayer.h"
+
+class RWindow;
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace MMF
+{
+
+/**
+ * @short Wrapper over the MMF video player utility (surface version)
+ *
+ * This implementation is used on devices with a graphics subsystem which
+ * supports surfaces.
+ *
+ * @see DsaVideoPlayer
+ */
+class SurfaceVideoPlayer
+ : public AbstractVideoPlayer
+{
+ Q_OBJECT
+
+public:
+ // Factory function
+ static SurfaceVideoPlayer* create(MediaObject *parent = 0,
+ const AbstractPlayer *player = 0);
+ ~SurfaceVideoPlayer();
+
+public Q_SLOTS:
+ void videoWindowSizeChanged();
+
+private:
+ SurfaceVideoPlayer(MediaObject *parent, const AbstractPlayer *player);
+
+ // AbstractVideoPlayer
+ void createPlayer();
+ void initVideoOutput();
+ void prepareCompleted();
+ void handleVideoWindowChanged();
+ void handleParametersChanged(VideoParameters parameters);
+
+ void addDisplayWindow(const TRect &rect);
+ void removeDisplayWindow();
+
+private:
+ // Window handle which has been passed to the MMF via
+ // CVideoPlayerUtility2::SetDisplayWindowL
+ RWindow* m_displayWindow;
+
+};
+
+}
+}
+
+QT_END_NAMESPACE
+
+#endif // !PHONON_MMF_VIDEOPLAYER_SURFACE_H
+
diff --git a/src/3rdparty/phonon/mmf/videowidget.cpp b/src/3rdparty/phonon/mmf/videowidget.cpp
new file mode 100644
index 0000000..d59e82a
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/videowidget.cpp
@@ -0,0 +1,192 @@
+/* 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 "mediaobject.h"
+#include "utils.h"
+
+#include "videowidget.h"
+
+#ifdef PHONON_MMF_VIDEO_SURFACES
+#include "videooutput_surface.h"
+#else
+#include "videooutput_dsa.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+using namespace Phonon;
+using namespace Phonon::MMF;
+
+/*! \class MMF::VideoWidget
+ \internal
+*/
+
+//-----------------------------------------------------------------------------
+// Constants
+//-----------------------------------------------------------------------------
+
+static const qreal DefaultBrightness = 1.0;
+static const qreal DefaultContrast = 1.0;
+static const qreal DefaultHue = 1.0;
+static const qreal DefaultSaturation = 1.0;
+
+
+//-----------------------------------------------------------------------------
+// Constructor / destructor
+//-----------------------------------------------------------------------------
+
+MMF::VideoWidget::VideoWidget(QWidget *parent)
+ : MediaNode(parent)
+#ifdef PHONON_MMF_VIDEO_SURFACES
+ , m_videoOutput(new SurfaceVideoOutput(parent))
+#else
+ , m_videoOutput(new DsaVideoOutput(parent))
+#endif
+ , m_brightness(DefaultBrightness)
+ , m_contrast(DefaultContrast)
+ , m_hue(DefaultHue)
+ , m_saturation(DefaultSaturation)
+{
+ TRACE_CONTEXT(VideoWidget::VideoWidget, EVideoApi);
+ TRACE_ENTRY_0();
+
+ parent->setProperty("_q_DummyWindowSurface", true);
+
+ TRACE_EXIT_0();
+}
+
+MMF::VideoWidget::~VideoWidget()
+{
+ TRACE_CONTEXT(VideoWidget::~VideoWidget, EVideoApi);
+ TRACE_ENTRY_0();
+
+ TRACE_EXIT_0();
+}
+
+#ifndef PHONON_MMF_VIDEO_SURFACES
+void MMF::VideoWidget::setAncestorMoveMonitor(AncestorMoveMonitor *monitor)
+{
+ static_cast<DsaVideoOutput *>(m_videoOutput.data())->setAncestorMoveMonitor(monitor);
+}
+#endif
+
+
+//-----------------------------------------------------------------------------
+// VideoWidgetInterface
+//-----------------------------------------------------------------------------
+
+Phonon::VideoWidget::AspectRatio MMF::VideoWidget::aspectRatio() const
+{
+ return m_videoOutput->aspectRatio();
+}
+
+void MMF::VideoWidget::setAspectRatio
+(Phonon::VideoWidget::AspectRatio aspectRatio)
+{
+ TRACE_CONTEXT(VideoWidget::setAspectRatio, EVideoApi);
+ TRACE("aspectRatio %d", aspectRatio);
+
+ m_videoOutput->setAspectRatio(aspectRatio);
+}
+
+qreal MMF::VideoWidget::brightness() const
+{
+ return m_brightness;
+}
+
+void MMF::VideoWidget::setBrightness(qreal brightness)
+{
+ TRACE_CONTEXT(VideoWidget::setBrightness, EVideoApi);
+ TRACE("brightness %f", brightness);
+
+ m_brightness = brightness;
+}
+
+Phonon::VideoWidget::ScaleMode MMF::VideoWidget::scaleMode() const
+{
+ return m_videoOutput->scaleMode();
+}
+
+void MMF::VideoWidget::setScaleMode(Phonon::VideoWidget::ScaleMode scaleMode)
+{
+ TRACE_CONTEXT(VideoWidget::setScaleMode, EVideoApi);
+ TRACE("setScaleMode %d", scaleMode);
+
+ m_videoOutput->setScaleMode(scaleMode);
+}
+
+qreal MMF::VideoWidget::contrast() const
+{
+ return m_contrast;
+}
+
+void MMF::VideoWidget::setContrast(qreal contrast)
+{
+ TRACE_CONTEXT(VideoWidget::setContrast, EVideoApi);
+ TRACE("contrast %f", contrast);
+
+ m_contrast = contrast;
+}
+
+qreal MMF::VideoWidget::hue() const
+{
+ return m_hue;
+}
+
+void MMF::VideoWidget::setHue(qreal hue)
+{
+ TRACE_CONTEXT(VideoWidget::setHue, EVideoApi);
+ TRACE("hue %f", hue);
+
+ m_hue = hue;
+}
+
+qreal MMF::VideoWidget::saturation() const
+{
+ return m_saturation;
+}
+
+void MMF::VideoWidget::setSaturation(qreal saturation)
+{
+ TRACE_CONTEXT(VideoWidget::setSaturation, EVideoApi);
+ TRACE("saturation %f", saturation);
+
+ m_saturation = saturation;
+}
+
+QWidget* MMF::VideoWidget::widget()
+{
+ return m_videoOutput.data();
+}
+
+//-----------------------------------------------------------------------------
+// MediaNode
+//-----------------------------------------------------------------------------
+
+void MMF::VideoWidget::connectMediaObject(MediaObject *mediaObject)
+{
+ mediaObject->setVideoOutput(m_videoOutput.data());
+}
+
+void MMF::VideoWidget::disconnectMediaObject(MediaObject *mediaObject)
+{
+ mediaObject->setVideoOutput(0);
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/3rdparty/phonon/mmf/videowidget.h b/src/3rdparty/phonon/mmf/videowidget.h
new file mode 100644
index 0000000..3b6283e
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/videowidget.h
@@ -0,0 +1,87 @@
+/* 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_VIDEOWIDGET_H
+#define PHONON_MMF_VIDEOWIDGET_H
+
+#include "abstractvideooutput.h"
+#include "mmf_medianode.h"
+
+#include <QtGui/QWidget>
+#include <phonon/videowidget.h>
+#include <phonon/videowidgetinterface.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Phonon
+{
+namespace MMF
+{
+#ifndef PHONON_MMF_VIDEO_SURFACES
+class AncestorMoveMonitor;
+#endif
+
+class VideoWidget : public MediaNode
+ , public Phonon::VideoWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(Phonon::VideoWidgetInterface)
+
+public:
+ VideoWidget(QWidget* parent);
+ ~VideoWidget();
+
+#ifndef PHONON_MMF_VIDEO_SURFACES
+ void setAncestorMoveMonitor(AncestorMoveMonitor *ancestorMoveMonitor);
+#endif
+
+ // VideoWidgetInterface
+ virtual Phonon::VideoWidget::AspectRatio aspectRatio() const;
+ virtual void setAspectRatio(Phonon::VideoWidget::AspectRatio aspectRatio);
+ virtual qreal brightness() const;
+ virtual void setBrightness(qreal brightness);
+ virtual Phonon::VideoWidget::ScaleMode scaleMode() const;
+ virtual void setScaleMode(Phonon::VideoWidget::ScaleMode scaleMode);
+ virtual qreal contrast() const;
+ virtual void setContrast(qreal constrast);
+ virtual qreal hue() const;
+ virtual void setHue(qreal hue);
+ virtual qreal saturation() const;
+ virtual void setSaturation(qreal saturation);
+ virtual QWidget *widget();
+
+protected:
+ // MediaNode
+ void connectMediaObject(MediaObject *mediaObject);
+ void disconnectMediaObject(MediaObject *mediaObject);
+
+private:
+ QScopedPointer<AbstractVideoOutput> m_videoOutput;
+
+ qreal m_brightness;
+ qreal m_contrast;
+ qreal m_hue;
+ qreal m_saturation;
+
+};
+}
+}
+
+QT_END_NAMESPACE
+
+#endif