summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp')
-rw-r--r--WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp533
1 files changed, 533 insertions, 0 deletions
diff --git a/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp b/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp
new file mode 100644
index 0000000..431e68e
--- /dev/null
+++ b/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp
@@ -0,0 +1,533 @@
+/*
+ Copyright (C) 2008 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 Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+#include "MediaPlayerPrivatePhonon.h"
+
+#include <limits>
+
+#include "CString.h"
+#include "FrameView.h"
+#include "GraphicsContext.h"
+#include "NotImplemented.h"
+#include "Widget.h"
+#include <wtf/HashSet.h>
+
+#include <QDebug>
+#include <QPainter>
+#include <QWidget>
+#include <QMetaEnum>
+#include <QUrl>
+#include <QEvent>
+#include <phonon>
+
+using namespace Phonon;
+
+#define LOG_MEDIAOBJECT() (LOG(Media,"%s", debugMediaObject(this, *m_mediaObject).constData()))
+
+static QByteArray debugMediaObject(WebCore::MediaPlayerPrivate* mediaPlayer, const MediaObject& mediaObject)
+{
+ QByteArray byteArray;
+ QTextStream stream(&byteArray);
+
+ const QMetaObject* metaObj = mediaPlayer->metaObject();
+ QMetaEnum phononStates = metaObj->enumerator(metaObj->indexOfEnumerator("PhononState"));
+
+ stream << "debugMediaObject -> Phonon::MediaObject(";
+ stream << "State: " << phononStates.valueToKey(mediaObject.state());
+ stream << " | Current time: " << mediaObject.currentTime();
+ stream << " | Remaining time: " << mediaObject.remainingTime();
+ stream << " | Total time: " << mediaObject.totalTime();
+ stream << " | Meta-data: ";
+ QMultiMap<QString, QString> map = mediaObject.metaData();
+ for (QMap<QString, QString>::const_iterator it = map.constBegin();
+ it != map.constEnd(); ++it) {
+ stream << "(" << it.key() << ", " << it.value() << ")";
+ }
+ stream << " | Has video: " << mediaObject.hasVideo();
+ stream << " | Is seekable: " << mediaObject.isSeekable();
+ stream << ")";
+
+ stream.flush();
+
+ return byteArray;
+}
+
+using namespace WTF;
+
+namespace WebCore {
+
+MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
+ : m_player(player)
+ , m_networkState(MediaPlayer::Empty)
+ , m_readyState(MediaPlayer::DataUnavailable)
+ , m_mediaObject(new MediaObject())
+ , m_videoWidget(new VideoWidget(0))
+ , m_audioOutput(new AudioOutput())
+ , m_isVisible(false)
+{
+ // Hint to Phonon to disable overlay painting
+ m_videoWidget->setAttribute(Qt::WA_DontShowOnScreen);
+
+ createPath(m_mediaObject, m_videoWidget);
+ createPath(m_mediaObject, m_audioOutput);
+
+ // Make sure we get updates for each frame
+ m_videoWidget->installEventFilter(this);
+ foreach(QWidget* widget, qFindChildren<QWidget*>(m_videoWidget)) {
+ widget->installEventFilter(this);
+ }
+
+ connect(m_mediaObject, SIGNAL(stateChanged(Phonon::State, Phonon::State)),
+ this, SLOT(stateChanged(Phonon::State, Phonon::State)));
+ connect(m_mediaObject, SIGNAL(tick(qint64)), this, SLOT(tick(qint64)));
+ connect(m_mediaObject, SIGNAL(metaDataChanged()), this, SLOT(metaDataChanged()));
+ connect(m_mediaObject, SIGNAL(seekableChanged(bool)), this, SLOT(seekableChanged(bool)));
+ connect(m_mediaObject, SIGNAL(hasVideoChanged(bool)), this, SLOT(hasVideoChanged(bool)));
+ connect(m_mediaObject, SIGNAL(bufferStatus(int)), this, SLOT(bufferStatus(int)));
+ connect(m_mediaObject, SIGNAL(finished()), this, SLOT(finished()));
+ connect(m_mediaObject, SIGNAL(currentSourceChanged(const Phonon::MediaSource&)),
+ this, SLOT(currentSourceChanged(const Phonon::MediaSource&)));
+ connect(m_mediaObject, SIGNAL(aboutToFinish()), this, SLOT(aboutToFinish()));
+ connect(m_mediaObject, SIGNAL(prefinishMarkReached(qint32)), this, SLOT(prefinishMarkReached(qint32)));
+ connect(m_mediaObject, SIGNAL(totalTimeChanged(qint64)), this, SLOT(totalTimeChanged(qint64)));
+}
+
+MediaPlayerPrivate::~MediaPlayerPrivate()
+{
+ LOG(Media, "MediaPlayerPrivatePhonon::dtor deleting videowidget");
+ m_videoWidget->close();
+ delete m_videoWidget;
+ m_videoWidget = 0;
+
+ LOG(Media, "MediaPlayerPrivatePhonon::dtor deleting audiooutput");
+ delete m_audioOutput;
+ m_audioOutput = 0;
+
+ LOG(Media, "MediaPlayerPrivatePhonon::dtor deleting mediaobject");
+ delete m_mediaObject;
+ m_mediaObject = 0;
+}
+
+void MediaPlayerPrivate::getSupportedTypes(HashSet<String>&)
+{
+ notImplemented();
+}
+
+bool MediaPlayerPrivate::hasVideo() const
+{
+ bool hasVideo = m_mediaObject->hasVideo();
+ LOG(Media, "MediaPlayerPrivatePhonon::hasVideo() -> %s", hasVideo ? "true" : "false");
+ return hasVideo;
+}
+
+void MediaPlayerPrivate::load(String url)
+{
+ LOG(Media, "MediaPlayerPrivatePhonon::load(\"%s\")", url.utf8().data());
+
+ // We are now loading
+ if (m_networkState != MediaPlayer::Loading) {
+ m_networkState = MediaPlayer::Loading;
+ m_player->networkStateChanged();
+ }
+
+ // And we don't have any data yet
+ if (m_readyState != MediaPlayer::DataUnavailable) {
+ m_readyState = MediaPlayer::DataUnavailable;
+ m_player->readyStateChanged();
+ }
+
+ m_mediaObject->setCurrentSource(QUrl(url));
+ m_audioOutput->setVolume(m_player->volume());
+ setVisible(m_player->visible());
+}
+
+void MediaPlayerPrivate::cancelLoad()
+{
+ notImplemented();
+}
+
+
+void MediaPlayerPrivate::play()
+{
+ LOG(Media, "MediaPlayerPrivatePhonon::play()");
+ m_mediaObject->play();
+}
+
+void MediaPlayerPrivate::pause()
+{
+ LOG(Media, "MediaPlayerPrivatePhonon::pause()");
+ m_mediaObject->pause();
+}
+
+
+bool MediaPlayerPrivate::paused() const
+{
+ bool paused = m_mediaObject->state() == Phonon::PausedState;
+ LOG(Media, "MediaPlayerPrivatePhonon::paused() --> %s", paused ? "true" : "false");
+ return paused;
+}
+
+void MediaPlayerPrivate::seek(float position)
+{
+ LOG(Media, "MediaPlayerPrivatePhonon::seek(%f)", position);
+
+ if (!m_mediaObject->isSeekable())
+ return;
+
+ if (position > duration())
+ position = duration();
+
+ m_mediaObject->seek(position * 1000.0f);
+}
+
+bool MediaPlayerPrivate::seeking() const
+{
+ return false;
+}
+
+float MediaPlayerPrivate::duration() const
+{
+ if (m_networkState < MediaPlayer::LoadedMetaData)
+ return 0.0f;
+
+ float duration = m_mediaObject->totalTime() / 1000.0f;
+
+ if (duration == 0.0f) // We are streaming
+ duration = std::numeric_limits<float>::infinity();
+
+ LOG(Media, "MediaPlayerPrivatePhonon::duration() --> %f", duration);
+ return duration;
+}
+
+float MediaPlayerPrivate::currentTime() const
+{
+ float currentTime = m_mediaObject->currentTime() / 1000.0f;
+
+ LOG(Media, "MediaPlayerPrivatePhonon::currentTime() --> %f", currentTime);
+ return currentTime;
+}
+
+void MediaPlayerPrivate::setEndTime(float endTime)
+{
+ notImplemented();
+}
+
+float MediaPlayerPrivate::maxTimeBuffered() const
+{
+ notImplemented();
+ return 0.0f;
+}
+
+float MediaPlayerPrivate::maxTimeSeekable() const
+{
+ notImplemented();
+ return 0.0f;
+}
+
+unsigned MediaPlayerPrivate::bytesLoaded() const
+{
+ notImplemented();
+ return 0;
+}
+
+bool MediaPlayerPrivate::totalBytesKnown() const
+{
+ //notImplemented();
+ return false;
+}
+
+unsigned MediaPlayerPrivate::totalBytes() const
+{
+ //notImplemented();
+ return 0;
+}
+
+void MediaPlayerPrivate::setRate(float)
+{
+ notImplemented();
+}
+
+void MediaPlayerPrivate::setVolume(float volume)
+{
+ LOG(Media, "MediaPlayerPrivatePhonon::setVolume()");
+ m_audioOutput->setVolume(volume);
+}
+
+void MediaPlayerPrivate::setMuted(bool muted)
+{
+ LOG(Media, "MediaPlayerPrivatePhonon::setMuted()");
+ m_audioOutput->setMuted(muted);
+}
+
+
+int MediaPlayerPrivate::dataRate() const
+{
+ // This is not used at the moment
+ return 0;
+}
+
+
+MediaPlayer::NetworkState MediaPlayerPrivate::networkState() const
+{
+ const QMetaObject* metaObj = this->metaObject();
+ QMetaEnum networkStates = metaObj->enumerator(metaObj->indexOfEnumerator("NetworkState"));
+ LOG(Media, "MediaPlayerPrivatePhonon::networkState() --> %s", networkStates.valueToKey(m_networkState));
+ return m_networkState;
+}
+
+MediaPlayer::ReadyState MediaPlayerPrivate::readyState() const
+{
+ const QMetaObject* metaObj = this->metaObject();
+ QMetaEnum readyStates = metaObj->enumerator(metaObj->indexOfEnumerator("ReadyState"));
+ LOG(Media, "MediaPlayerPrivatePhonon::readyState() --> %s", readyStates.valueToKey(m_readyState));
+ return m_readyState;
+}
+
+void MediaPlayerPrivate::updateStates()
+{
+ MediaPlayer::NetworkState oldNetworkState = m_networkState;
+ MediaPlayer::ReadyState oldReadyState = m_readyState;
+
+ Phonon::State phononState = m_mediaObject->state();
+
+ if (phononState == Phonon::StoppedState) {
+ if (oldNetworkState < MediaPlayer::LoadedMetaData) {
+ m_networkState = MediaPlayer::LoadedMetaData;
+ m_readyState = MediaPlayer::DataUnavailable;
+ m_mediaObject->pause();
+ }
+ } else if (phononState == Phonon::PausedState) {
+ m_networkState = MediaPlayer::LoadedFirstFrame;
+ m_readyState = MediaPlayer::CanPlayThrough;
+ } else if (phononState == Phonon::ErrorState) {
+ if (!m_mediaObject || m_mediaObject->errorType() == Phonon::FatalError) {
+ m_networkState = MediaPlayer::LoadFailed;
+ m_readyState = MediaPlayer::DataUnavailable;
+ cancelLoad();
+ } else {
+ m_mediaObject->pause();
+ }
+ }
+
+ if (seeking())
+ m_readyState = MediaPlayer::DataUnavailable;
+
+ if (m_networkState != oldNetworkState) {
+ const QMetaObject* metaObj = this->metaObject();
+ QMetaEnum networkStates = metaObj->enumerator(metaObj->indexOfEnumerator("NetworkState"));
+ LOG(Media, "Network state changed from '%s' to '%s'",
+ networkStates.valueToKey(oldNetworkState),
+ networkStates.valueToKey(m_networkState));
+ m_player->networkStateChanged();
+ }
+
+ if (m_readyState != oldReadyState) {
+ const QMetaObject* metaObj = this->metaObject();
+ QMetaEnum readyStates = metaObj->enumerator(metaObj->indexOfEnumerator("ReadyState"));
+ LOG(Media, "Ready state changed from '%s' to '%s'",
+ readyStates.valueToKey(oldReadyState),
+ readyStates.valueToKey(m_readyState));
+ m_player->readyStateChanged();
+ }
+}
+
+void MediaPlayerPrivate::setVisible(bool visible)
+{
+ m_isVisible = visible;
+ LOG(Media, "MediaPlayerPrivatePhonon::setVisible(%s)", visible ? "true" : "false");
+
+ m_videoWidget->setVisible(m_isVisible);
+}
+
+void MediaPlayerPrivate::setRect(const IntRect& newRect)
+{
+ if (!m_videoWidget)
+ return;
+
+ LOG(Media, "MediaPlayerPrivatePhonon::setRect(%d,%d %dx%d)",
+ newRect.x(), newRect.y(),
+ newRect.width(), newRect.height());
+
+ QRect currentRect = m_videoWidget->rect();
+
+ if (newRect.width() != currentRect.width() || newRect.height() != currentRect.height())
+ m_videoWidget->resize(newRect.width(), newRect.height());
+}
+
+
+void MediaPlayerPrivate::loadStateChanged()
+{
+ notImplemented();
+}
+
+void MediaPlayerPrivate::rateChanged()
+{
+ notImplemented();
+}
+
+void MediaPlayerPrivate::sizeChanged()
+{
+ notImplemented();
+}
+
+void MediaPlayerPrivate::timeChanged()
+{
+ notImplemented();
+}
+
+void MediaPlayerPrivate::volumeChanged()
+{
+ notImplemented();
+}
+
+void MediaPlayerPrivate::didEnd()
+{
+ notImplemented();
+}
+
+void MediaPlayerPrivate::loadingFailed()
+{
+ notImplemented();
+}
+
+IntSize MediaPlayerPrivate::naturalSize() const
+{
+ if (!hasVideo()) {
+ LOG(Media, "MediaPlayerPrivatePhonon::naturalSize() -> %dx%d",
+ 0, 0);
+ return IntSize();
+ }
+
+ if (m_networkState < MediaPlayer::LoadedMetaData) {
+ LOG(Media, "MediaPlayerPrivatePhonon::naturalSize() -> %dx%d",
+ 0, 0);
+ return IntSize();
+ }
+
+ QSize videoSize = m_videoWidget->sizeHint();
+ IntSize naturalSize(videoSize.width(), videoSize.height());
+ LOG(Media, "MediaPlayerPrivatePhonon::naturalSize() -> %dx%d",
+ naturalSize.width(), naturalSize.height());
+ return naturalSize;
+}
+
+bool MediaPlayerPrivate::eventFilter(QObject* obj, QEvent* event)
+{
+ if (event->type() == QEvent::Paint)
+ m_player->repaint();
+
+ return QObject::eventFilter(obj, event);
+}
+
+void MediaPlayerPrivate::repaint()
+{
+ m_player->repaint();
+}
+
+void MediaPlayerPrivate::paint(GraphicsContext* graphicsContect, const IntRect& rect)
+{
+ if (graphicsContect->paintingDisabled())
+ return;
+
+ if (!m_isVisible)
+ return;
+
+ QPainter* painter = graphicsContect->platformContext();
+
+ painter->fillRect(rect, Qt::black);
+
+ m_videoWidget->render(painter, QPoint(rect.x(), rect.y()),
+ QRegion(0, 0, rect.width(), rect.height()));
+}
+
+// ====================== Phonon::MediaObject signals ======================
+
+void MediaPlayerPrivate::stateChanged(Phonon::State newState, Phonon::State oldState)
+{
+ const QMetaObject* metaObj = this->metaObject();
+ QMetaEnum phononStates = metaObj->enumerator(metaObj->indexOfEnumerator("PhononState"));
+ LOG(Media, "MediaPlayerPrivatePhonon::stateChanged(newState=%s, oldState=%s)",
+ phononStates.valueToKey(newState), phononStates.valueToKey(oldState));
+
+ updateStates();
+}
+
+void MediaPlayerPrivate::tick(qint64)
+{
+ updateStates();
+ m_player->timeChanged();
+}
+
+void MediaPlayerPrivate::metaDataChanged()
+{
+ LOG(Media, "MediaPlayerPrivatePhonon::metaDataChanged()");
+ LOG_MEDIAOBJECT();
+}
+
+void MediaPlayerPrivate::seekableChanged(bool)
+{
+ notImplemented();
+ LOG_MEDIAOBJECT();
+}
+
+void MediaPlayerPrivate::hasVideoChanged(bool hasVideo)
+{
+ LOG(Media, "MediaPlayerPrivatePhonon::hasVideoChanged(%s)", hasVideo ? "true" : "false");
+}
+
+void MediaPlayerPrivate::bufferStatus(int)
+{
+ notImplemented();
+ LOG_MEDIAOBJECT();
+}
+
+void MediaPlayerPrivate::finished()
+{
+ notImplemented();
+ LOG_MEDIAOBJECT();
+}
+
+void MediaPlayerPrivate::currentSourceChanged(const Phonon::MediaSource&)
+{
+ notImplemented();
+ LOG_MEDIAOBJECT();
+}
+
+void MediaPlayerPrivate::aboutToFinish()
+{
+ notImplemented();
+ LOG_MEDIAOBJECT();
+}
+
+void MediaPlayerPrivate::prefinishMarkReached(qint32)
+{
+ notImplemented();
+ LOG_MEDIAOBJECT();
+}
+
+void MediaPlayerPrivate::totalTimeChanged(qint64 totalTime)
+{
+ LOG(Media, "MediaPlayerPrivatePhonon::totalTimeChanged(%d)", totalTime);
+ LOG_MEDIAOBJECT();
+}
+
+} // namespace WebCore
+
+#include "moc_MediaPlayerPrivatePhonon.cpp"