summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2010-10-10 21:44:01 +0200
committerQt Continuous Integration System <qt-info@nokia.com>2010-10-10 21:44:01 +0200
commit79f20ff18232f5b9a8df061a74b08948dadb7b8b (patch)
treee80392dede2042da4275b718ee8622c3c9fe90ad
parent46822d7091ef05e64e363e7209ea3e613e4d386d (diff)
parent71af72bc037db6bac023bf9a0bbf6032c06b2d29 (diff)
downloadqt4-tools-79f20ff18232f5b9a8df061a74b08948dadb7b8b.tar.gz
Merge branch '4.6' of scm.dev.nokia.troll.no:qt/qt-s60-public into 4.6-integration
* '4.6' of scm.dev.nokia.troll.no:qt/qt-s60-public: Added qmake check for presence of RHttpDownloadMgr header qmediaplayer: show buffer status of 0% Progressive download in Phonon MMF backend: integrated with player Progressive download in Phonon MMF backend: added download managers
-rw-r--r--demos/qmediaplayer/mediaplayer.cpp2
-rw-r--r--src/3rdparty/phonon/mmf/abstractmediaplayer.cpp170
-rw-r--r--src/3rdparty/phonon/mmf/abstractmediaplayer.h22
-rw-r--r--src/3rdparty/phonon/mmf/abstractvideoplayer.cpp24
-rw-r--r--src/3rdparty/phonon/mmf/abstractvideoplayer.h5
-rw-r--r--src/3rdparty/phonon/mmf/audioplayer.cpp18
-rw-r--r--src/3rdparty/phonon/mmf/audioplayer.h5
-rw-r--r--src/3rdparty/phonon/mmf/download.cpp194
-rw-r--r--src/3rdparty/phonon/mmf/download.h109
-rw-r--r--src/3rdparty/phonon/mmf/mediaobject.cpp36
-rw-r--r--src/3rdparty/phonon/mmf/mediaobject.h1
-rw-r--r--src/plugins/phonon/mmf/mmf.pro50
12 files changed, 572 insertions, 64 deletions
diff --git a/demos/qmediaplayer/mediaplayer.cpp b/demos/qmediaplayer/mediaplayer.cpp
index 3cb06167ed..97a8e35f03 100644
--- a/demos/qmediaplayer/mediaplayer.cpp
+++ b/demos/qmediaplayer/mediaplayer.cpp
@@ -716,7 +716,7 @@ void MediaPlayer::openFile()
void MediaPlayer::bufferStatus(int percent)
{
- if (percent == 0 || percent == 100)
+ if (percent == 100)
progressLabel->setText(QString());
else {
QString str = QString::fromLatin1("(%1%)").arg(percent);
diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp
index 3702560c5f..dfc58409ff 100644
--- a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp
+++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp
@@ -51,10 +51,15 @@ MMF::AbstractMediaPlayer::AbstractMediaPlayer
, 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()));
@@ -183,6 +188,7 @@ void MMF::AbstractMediaPlayer::seek(qint64 ms)
}
doSeek(ms);
+ m_position = ms;
resetMarksIfRewound();
if(wasPlaying && state() != ErrorState) {
@@ -207,6 +213,11 @@ 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);
@@ -247,7 +258,19 @@ void MMF::AbstractMediaPlayer::open()
symbianErr = openFile(*file);
if (KErrNone != symbianErr)
errorMessage = tr("Error opening file");
- } else {
+ }
+#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)));
+ m_download->start();
+ }
+#endif
+ else {
symbianErr = openUrl(url.toString());
if (KErrNone != symbianErr)
errorMessage = tr("Error opening URL");
@@ -288,6 +311,16 @@ void MMF::AbstractMediaPlayer::open()
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);
@@ -374,7 +407,8 @@ void MMF::AbstractMediaPlayer::bufferingComplete()
{
stopBufferStatusTimer();
emit MMF::AbstractPlayer::bufferStatus(100);
- changeState(m_stateBeforeBuffering);
+ if (!progressiveDownloadStalled())
+ changeState(m_stateBeforeBuffering);
}
void MMF::AbstractMediaPlayer::maxVolumeChanged(int mmfMaxVolume)
@@ -385,13 +419,30 @@ void MMF::AbstractMediaPlayer::maxVolumeChanged(int mmfMaxVolume)
void MMF::AbstractMediaPlayer::loadingComplete(int error)
{
- Q_ASSERT(Phonon::LoadingState == state());
-
- if (KErrNone == error) {
- updateMetaData();
- changeState(StoppedState);
+ 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 {
- setError(tr("Loading clip failed"), error);
+ Q_ASSERT(Phonon::LoadingState == state());
+ if (KErrNone == error) {
+ updateMetaData();
+ changeState(StoppedState);
+ } else {
+ if (isProgressiveDownload() && KErrCorrupt == error) {
+ setProgressiveDownloadStalled();
+ } else {
+ setError(tr("Loading clip failed"), error);
+ }
+ }
}
}
@@ -415,8 +466,12 @@ void MMF::AbstractMediaPlayer::playbackComplete(int error)
QMetaObject::invokeMethod(m_parent, "switchToNextSource", Qt::QueuedConnection);
}
else {
- setError(tr("Playback complete"), error);
- emit finished();
+ if (isProgressiveDownload() && KErrCorrupt == error) {
+ setProgressiveDownloadStalled();
+ } else {
+ setError(tr("Playback complete"), error);
+ emit finished();
+ }
}
}
@@ -425,15 +480,36 @@ qint64 MMF::AbstractMediaPlayer::toMilliSeconds(const TTimeIntervalMicroSeconds
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 current = currentTime();
- emitMarksIfReached(current);
- emit MMF::AbstractPlayer::tick(current);
+ 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)
@@ -458,7 +534,7 @@ void MMF::AbstractMediaPlayer::emitMarksIfReached(qint64 current)
void MMF::AbstractMediaPlayer::resetMarksIfRewound()
{
- const qint64 current = currentTime();
+ const qint64 current = getCurrentTime();
const qint64 total = totalTime();
const qint64 remaining = total - current;
@@ -487,10 +563,74 @@ void MMF::AbstractMediaPlayer::startPlayback()
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()
{
- emit MMF::AbstractPlayer::bufferStatus(bufferStatus());
+ // 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
{
diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.h b/src/3rdparty/phonon/mmf/abstractmediaplayer.h
index e795ecbf91..c3b4528f6f 100644
--- a/src/3rdparty/phonon/mmf/abstractmediaplayer.h
+++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.h
@@ -23,6 +23,9 @@ along with this library. If not, see <http://www.gnu.org/licenses/>.
#include <QScopedPointer>
#include <e32std.h>
#include "abstractplayer.h"
+#ifdef PHONON_MMF_PROGRESSIVE_DOWNLOAD
+# include "download.h"
+#endif
class RFile;
@@ -48,6 +51,7 @@ protected:
public:
virtual void open();
+ virtual void close();
// MediaObjectInterface
virtual void play();
@@ -55,6 +59,7 @@ public:
virtual void stop();
virtual void seek(qint64 milliseconds);
virtual bool isSeekable() const;
+ virtual qint64 currentTime() const;
virtual void volumeChanged(qreal volume);
protected:
@@ -68,12 +73,15 @@ protected:
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) = 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;
@@ -86,6 +94,9 @@ protected:
static qint64 toMilliSeconds(const TTimeIntervalMicroSeconds &);
+ bool isProgressiveDownload() const;
+ bool progressiveDownloadStalled() const;
+
private:
void startPositionTimer();
void stopPositionTimer();
@@ -96,6 +107,7 @@ private:
void emitMarksIfReached(qint64 position);
void resetMarksIfRewound();
void startPlayback();
+ void setProgressiveDownloadStalled();
enum Pending {
NothingPending,
@@ -108,6 +120,10 @@ private:
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;
@@ -115,6 +131,7 @@ private:
Pending m_pending;
QScopedPointer<QTimer> m_positionTimer;
+ qint64 m_position;
QScopedPointer<QTimer> m_bufferStatusTimer;
PrivateState m_stateBeforeBuffering;
@@ -127,6 +144,11 @@ private:
// 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;
};
diff --git a/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp b/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp
index fb20bea018..1ab5baefcc 100644
--- a/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp
+++ b/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp
@@ -16,6 +16,7 @@ along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <QDir>
#include <QUrl>
#include <QTimer>
#include <QWidget>
@@ -132,6 +133,13 @@ int MMF::AbstractVideoPlayer::setDeviceVolume(int 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));
@@ -157,7 +165,7 @@ int MMF::AbstractVideoPlayer::bufferStatus() const
return result;
}
-void MMF::AbstractVideoPlayer::close()
+void MMF::AbstractVideoPlayer::doClose()
{
m_player->Close();
}
@@ -167,9 +175,9 @@ bool MMF::AbstractVideoPlayer::hasVideo() const
return true;
}
-qint64 MMF::AbstractVideoPlayer::currentTime() const
+qint64 MMF::AbstractVideoPlayer::getCurrentTime() const
{
- TRACE_CONTEXT(AbstractVideoPlayer::currentTime, EVideoApi);
+ TRACE_CONTEXT(AbstractVideoPlayer::getCurrentTime, EVideoApi);
TTimeIntervalMicroSeconds us;
TRAPD(err, us = m_player->PositionL())
@@ -246,7 +254,9 @@ void MMF::AbstractVideoPlayer::MvpuoOpenComplete(TInt aError)
TRACE_CONTEXT(AbstractVideoPlayer::MvpuoOpenComplete, EVideoApi);
TRACE_ENTRY("state %d error %d", state(), aError);
- __ASSERT_ALWAYS(LoadingState == state(), Utils::panic(InvalidStatePanic));
+ __ASSERT_ALWAYS(LoadingState == state() ||
+ progressiveDownloadStalled() && BufferingState == state(),
+ Utils::panic(InvalidStatePanic));
if (KErrNone == aError)
m_player->Prepare();
@@ -261,7 +271,9 @@ void MMF::AbstractVideoPlayer::MvpuoPrepareComplete(TInt aError)
TRACE_CONTEXT(AbstractVideoPlayer::MvpuoPrepareComplete, EVideoApi);
TRACE_ENTRY("state %d error %d", state(), aError);
- __ASSERT_ALWAYS(LoadingState == state(), Utils::panic(InvalidStatePanic));
+ __ASSERT_ALWAYS(LoadingState == state() ||
+ progressiveDownloadStalled() && BufferingState == state(),
+ Utils::panic(InvalidStatePanic));
TRAPD(err, getVideoClipParametersL(aError));
@@ -470,7 +482,7 @@ void MMF::AbstractVideoPlayer::updateScaleFactors(const QSize &windowSize, bool
void MMF::AbstractVideoPlayer::parametersChanged(VideoParameters parameters)
{
- if (state() == LoadingState)
+ if (state() == LoadingState || progressiveDownloadStalled() && BufferingState == state())
m_pendingChanges |= parameters;
else
handleParametersChanged(parameters);
diff --git a/src/3rdparty/phonon/mmf/abstractvideoplayer.h b/src/3rdparty/phonon/mmf/abstractvideoplayer.h
index 3ff3c75d7d..3bc5c7c27a 100644
--- a/src/3rdparty/phonon/mmf/abstractvideoplayer.h
+++ b/src/3rdparty/phonon/mmf/abstractvideoplayer.h
@@ -64,21 +64,22 @@ public:
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);
virtual int openDescriptor(const TDesC8 &des);
virtual int bufferStatus() const;
- virtual void close();
+ virtual void doClose();
// MediaObjectInterface
virtual bool hasVideo() const;
- virtual qint64 currentTime() 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;
diff --git a/src/3rdparty/phonon/mmf/audioplayer.cpp b/src/3rdparty/phonon/mmf/audioplayer.cpp
index 7c8b9bd04f..dc5c800df1 100644
--- a/src/3rdparty/phonon/mmf/audioplayer.cpp
+++ b/src/3rdparty/phonon/mmf/audioplayer.cpp
@@ -16,6 +16,7 @@ along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <QDir>
#include <QUrl>
#include "audioplayer.h"
@@ -109,6 +110,13 @@ int MMF::AudioPlayer::setDeviceVolume(int mmfVolume)
#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));
@@ -150,7 +158,7 @@ int MMF::AudioPlayer::bufferStatus() const
return result;
}
-void MMF::AudioPlayer::close()
+void MMF::AudioPlayer::doClose()
{
m_player->Close();
}
@@ -160,9 +168,9 @@ bool MMF::AudioPlayer::hasVideo() const
return false;
}
-qint64 MMF::AudioPlayer::currentTime() const
+qint64 MMF::AudioPlayer::getCurrentTime() const
{
- TRACE_CONTEXT(AudioPlayer::currentTime, EAudioApi);
+ TRACE_CONTEXT(AudioPlayer::getCurrentTime, EAudioApi);
TTimeIntervalMicroSeconds us;
const TInt err = m_player->GetPosition(us);
@@ -203,7 +211,9 @@ void MMF::AudioPlayer::MapcInitComplete(TInt aError,
TRACE_CONTEXT(AudioPlayer::MapcInitComplete, EAudioInternal);
TRACE_ENTRY("state %d error %d", state(), aError);
- __ASSERT_ALWAYS(LoadingState == state(), Utils::panic(InvalidStatePanic));
+ __ASSERT_ALWAYS(LoadingState == state() ||
+ progressiveDownloadStalled() && BufferingState == state(),
+ Utils::panic(InvalidStatePanic));
if (KErrNone == aError) {
maxVolumeChanged(m_player->MaxVolume());
diff --git a/src/3rdparty/phonon/mmf/audioplayer.h b/src/3rdparty/phonon/mmf/audioplayer.h
index e43caddbf2..cf4f6d5ccd 100644
--- a/src/3rdparty/phonon/mmf/audioplayer.h
+++ b/src/3rdparty/phonon/mmf/audioplayer.h
@@ -65,18 +65,19 @@ typedef CMdaAudioPlayerUtility NativePlayer;
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);
virtual int openDescriptor(const TDesC8 &des);
virtual int bufferStatus() const;
- virtual void close();
+ virtual void doClose();
// MediaObjectInterface
virtual bool hasVideo() const;
- virtual qint64 currentTime() const;
virtual qint64 totalTime() const;
// AbstractMediaPlayer
+ virtual qint64 getCurrentTime() const;
virtual int numberOfMetaDataEntries() const;
virtual QPair<QString, QString> metaDataEntry(int index) const;
diff --git a/src/3rdparty/phonon/mmf/download.cpp b/src/3rdparty/phonon/mmf/download.cpp
new file mode 100644
index 0000000000..7b80e4a782
--- /dev/null
+++ b/src/3rdparty/phonon/mmf/download.cpp
@@ -0,0 +1,194 @@
+/* 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>
+
+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()
+{
+ m_downloadManager.Disconnect();
+ m_downloadManager.Close();
+}
+
+bool DownloadPrivate::start()
+{
+ 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
+ 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()
+{
+ TRACE_CONTEXT(Download::start, EVideoApi);
+ TRACE_ENTRY_0();
+ Q_ASSERT(Idle == m_state);
+ const bool ok = m_private->start();
+ 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 0000000000..bda7963049
--- /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();
+ 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();
+ 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/mediaobject.cpp b/src/3rdparty/phonon/mmf/mediaobject.cpp
index 98326b8d40..2c7a7efe83 100644
--- a/src/3rdparty/phonon/mmf/mediaobject.cpp
+++ b/src/3rdparty/phonon/mmf/mediaobject.cpp
@@ -61,6 +61,9 @@ MMF::MediaObject::MediaObject(QObject *parent) : MMF::MediaNode::MediaNode(paren
TRACE_CONTEXT(MediaObject::MediaObject, EAudioApi);
TRACE_ENTRY_0();
+ const int err = m_fileServer.Connect();
+ QT_TRAP_THROWING(User::LeaveIfError(err));
+
Q_UNUSED(parent);
TRACE_EXIT_0();
@@ -99,12 +102,6 @@ bool MMF::MediaObject::openRecognizer()
return false;
}
- err = m_fileServer.Connect();
- if (KErrNone != err) {
- TRACE("RFs::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();
@@ -127,13 +124,8 @@ MMF::MediaType MMF::MediaObject::fileMediaType
MediaType result = MediaTypeUnknown;
if (openRecognizer()) {
-
- const QHBufC fileNameSymbian(QDir::toNativeSeparators(fileName));
-
- Q_ASSERT(!m_file);
- m_file = new RFile;
- TInt err = m_file->Open(m_fileServer, *fileNameSymbian, EFileRead | EFileShareReadersOnly);
-
+ TInt err = openFileHandle(fileName);
+ const QHBufC nativeFileName(QDir::toNativeSeparators(fileName));
if (KErrNone == err) {
TDataRecognitionResult recognizerResult;
err = m_recognizer.RecognizeData(*m_file, recognizerResult);
@@ -141,16 +133,30 @@ MMF::MediaType MMF::MediaObject::fileMediaType
const TPtrC mimeType = recognizerResult.iDataType.Des();
result = Utils::mimeTypeToMediaType(mimeType);
} else {
- TRACE("RApaLsSession::RecognizeData filename %S error %d", fileNameSymbian.data(), err);
+ TRACE("RApaLsSession::RecognizeData filename %S error %d", nativeFileName.data(), err);
}
} else {
- TRACE("RFile::Open filename %S error %d", fileNameSymbian.data(), err);
+ 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);
diff --git a/src/3rdparty/phonon/mmf/mediaobject.h b/src/3rdparty/phonon/mmf/mediaobject.h
index 5399e27216..5d785fb108 100644
--- a/src/3rdparty/phonon/mmf/mediaobject.h
+++ b/src/3rdparty/phonon/mmf/mediaobject.h
@@ -89,6 +89,7 @@ public:
void setVideoOutput(AbstractVideoOutput* videoOutput);
+ int openFileHandle(const QString &fileName);
RFile* file() const;
QResource* resource() const;
diff --git a/src/plugins/phonon/mmf/mmf.pro b/src/plugins/phonon/mmf/mmf.pro
index 7a6fdf8365..ac111881bf 100644
--- a/src/plugins/phonon/mmf/mmf.pro
+++ b/src/plugins/phonon/mmf/mmf.pro
@@ -75,25 +75,37 @@ symbian {
$$PHONON_MMF_DIR/utils.cpp \
$$PHONON_MMF_DIR/videowidget.cpp
- # Test for whether the build environment supports video rendering to graphics
- # surfaces.
- symbian:exists($${EPOCROOT}epoc32/include/platform/videoplayer2.h) {
- HEADERS += \
- $$PHONON_MMF_DIR/videooutput_surface.h \
- $$PHONON_MMF_DIR/videoplayer_surface.h
- SOURCES += \
- $$PHONON_MMF_DIR/videooutput_surface.cpp \
- $$PHONON_MMF_DIR/videoplayer_surface.cpp
- DEFINES += PHONON_MMF_VIDEO_SURFACES
- } else {
- HEADERS += \
- $$PHONON_MMF_DIR/ancestormovemonitor.h \
- $$PHONON_MMF_DIR/videooutput_dsa.h \
- $$PHONON_MMF_DIR/videoplayer_dsa.h
- SOURCES += \
- $$PHONON_MMF_DIR/ancestormovemonitor.cpp \
- $$PHONON_MMF_DIR/videooutput_dsa.cpp \
- $$PHONON_MMF_DIR/videoplayer_dsa.cpp \
+ symbian {
+ # Test for whether the build environment supports video rendering to graphics
+ # surfaces.
+ exists($${EPOCROOT}epoc32/include/platform/videoplayer2.h) {
+ HEADERS += \
+ $$PHONON_MMF_DIR/videooutput_surface.h \
+ $$PHONON_MMF_DIR/videoplayer_surface.h
+ SOURCES += \
+ $$PHONON_MMF_DIR/videooutput_surface.cpp \
+ $$PHONON_MMF_DIR/videoplayer_surface.cpp
+ DEFINES += PHONON_MMF_VIDEO_SURFACES
+ } else {
+ HEADERS += \
+ $$PHONON_MMF_DIR/ancestormovemonitor.h \
+ $$PHONON_MMF_DIR/videooutput_dsa.h \
+ $$PHONON_MMF_DIR/videoplayer_dsa.h
+ SOURCES += \
+ $$PHONON_MMF_DIR/ancestormovemonitor.cpp \
+ $$PHONON_MMF_DIR/videooutput_dsa.cpp \
+ $$PHONON_MMF_DIR/videoplayer_dsa.cpp \
+ }
+
+ # Test whether the build environment includes support for the Download Manager
+ # API, required for Progressive Download
+ exists($${EPOCROOT}epoc32/include/downloadmgrclient.h) | \
+ exists($${EPOCROOT}epoc32/include/mw/downloadmgrclient.h) {
+ HEADERS += $$PHONON_MMF_DIR/download.h
+ SOURCES += $$PHONON_MMF_DIR/download.cpp
+ LIBS += -ldownloadmgr
+ DEFINES += PHONON_MMF_PROGRESSIVE_DOWNLOAD
+ }
}
LIBS += -lcone