From 0c8d49ca802da435107c489142064e2736b7e10f Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Thu, 18 Mar 2010 08:30:45 +0000 Subject: Added support for video surfaces to Phonon MMF backend Symbian^3 introduces a new compositing graphics subsystem in which non-UI content such as video is provided by client applications via graphics surfaces. This patch modifies the video playback part of the Phonon MMF backend so that, on devices which use the new graphics architecture (NGA), video is rendered to a surface. On devices which use the legacy graphics architecture, the existing video rendering path, which uses Direct Screen Access (DSA) is maintained. On NGA devices, video playback applications do not deal with surfaces directly; instead, they use a new MMF client API called CVideoPlayerUtility2. The implementation of this API takes care of creating a graphics surface, registering it with the window manager, and directing the output of the video decoder into this surface. CVideoPlayerUtility2 inherits from the legacy video playback API, CVideoPlayerUtility, deprecating certain functions and adding new ones. The main changes involved in modifying CVideoPlayerUtility client code to instead use CVideoPlayerUtility2 are: 1. CVideoPlayerUtility requires a window handle to be provided at object construction time. The CVideoPlayerUtility2 constructor does not take a window handle; it is provided by the client later via the SetDisplayWindowL function. 2. CVideoPlayerUtility requires the client to provide an absolute screen rectangle at construction time, and then to call SetDisplayWindowL whenever this rectangle changes due to either window repositioning or resizing. CVideoPlayerUtility2 requires the client to provide a display rectangle which is relative to the display window. This rectangle must be updated via SetVideoExtentL / SetWindowClipRectL when the window is resized, but no update is required when the window is repositioned - the compositing window system takes care of repositioning the video content on the screen. 3. CVideoPlayerUtility requires the client to paint transparent black into the region of the window in which video will be displayed. CVideoPlayerUtility2 does not require the client to paint the video window. In order to accomodate these differences, the existing VideoPlayer and VideoOutput classes are replaced with AbstractVideoPlayer and AbstractVideoOutput respectively. These abstract base classes encapsulate functionality which is common between the DSA and surface rendering client code. Because CVideoPlayerUtility2 inherits from CVideoPlayerUtility, AbstractVideoPlayer is able to hold a pointer to CVideoPlayerUtility, via which it controls functionality which is not affected by the details of the rendering path, such as play/pause/stop, seek and metadata access. The three areas of divergence listed above are encapsulated in the derived classes DsaVideoOutput/SurfaceVideoOutput and DsaVideoPlayer/ SurfaceVideoPlayer. Of the three, (1) and (3) are fairly straightforward. For DSA video playback, the need to respond to changes in video widget absolute screen position in (2) necessitated the AncestorMoveMonitor class, which installs an event filter on each ancestor of the video widget. This class is not required for surface video playback and is therefore removed from the surface-rendering code path. Selection of either the DSA- or surface-rendering code path is done at qmake time, via the exists(...) check introduced in mmf.pro. This checks for existence of the header in which CVideoPlayerUtility2 is defined; if this file is found, surface rendering is selected, otherwise the DSA rendering version of the backend is built. Note that this approach is not completely robust, since it is possible for an environment to include the videoplayer2.h header and yet be configured to use the legacy graphics subsystem. This could be dealt with by instead performing the check for surface support at configuration time, building and executing a small Symbian program which will return different output according to which of the two graphics subsystems is in use. Task-number: QTBUG-8919 Reviewed-by: Frans Englich --- src/3rdparty/phonon/mmf/abstractaudioeffect.cpp | 1 - src/3rdparty/phonon/mmf/abstractaudioeffect.h | 1 - src/3rdparty/phonon/mmf/abstractplayer.cpp | 2 +- src/3rdparty/phonon/mmf/abstractplayer.h | 7 +- src/3rdparty/phonon/mmf/abstractvideooutput.cpp | 177 +++++++ src/3rdparty/phonon/mmf/abstractvideooutput.h | 93 ++++ src/3rdparty/phonon/mmf/abstractvideoplayer.cpp | 490 ++++++++++++++++++ src/3rdparty/phonon/mmf/abstractvideoplayer.h | 171 ++++++ src/3rdparty/phonon/mmf/ancestormovemonitor.cpp | 13 +- src/3rdparty/phonon/mmf/ancestormovemonitor.h | 10 +- src/3rdparty/phonon/mmf/backend.cpp | 12 +- src/3rdparty/phonon/mmf/backend.h | 5 + src/3rdparty/phonon/mmf/defs.h | 9 + src/3rdparty/phonon/mmf/mediaobject.cpp | 16 +- src/3rdparty/phonon/mmf/mediaobject.h | 4 +- src/3rdparty/phonon/mmf/mmf_videoplayer.cpp | 658 ------------------------ src/3rdparty/phonon/mmf/mmf_videoplayer.h | 138 ----- src/3rdparty/phonon/mmf/videooutput.cpp | 303 ----------- src/3rdparty/phonon/mmf/videooutput.h | 105 ---- src/3rdparty/phonon/mmf/videooutput_dsa.cpp | 177 +++++++ src/3rdparty/phonon/mmf/videooutput_dsa.h | 109 ++++ src/3rdparty/phonon/mmf/videooutput_surface.cpp | 87 ++++ src/3rdparty/phonon/mmf/videooutput_surface.h | 66 +++ src/3rdparty/phonon/mmf/videoplayer_dsa.cpp | 285 ++++++++++ src/3rdparty/phonon/mmf/videoplayer_dsa.h | 92 ++++ src/3rdparty/phonon/mmf/videoplayer_surface.cpp | 150 ++++++ src/3rdparty/phonon/mmf/videoplayer_surface.h | 78 +++ src/3rdparty/phonon/mmf/videowidget.cpp | 23 +- src/3rdparty/phonon/mmf/videowidget.h | 13 +- src/plugins/phonon/mmf/mmf.pro | 33 +- 30 files changed, 2084 insertions(+), 1244 deletions(-) create mode 100644 src/3rdparty/phonon/mmf/abstractvideooutput.cpp create mode 100644 src/3rdparty/phonon/mmf/abstractvideooutput.h create mode 100644 src/3rdparty/phonon/mmf/abstractvideoplayer.cpp create mode 100644 src/3rdparty/phonon/mmf/abstractvideoplayer.h delete mode 100644 src/3rdparty/phonon/mmf/mmf_videoplayer.cpp delete mode 100644 src/3rdparty/phonon/mmf/mmf_videoplayer.h delete mode 100644 src/3rdparty/phonon/mmf/videooutput.cpp delete mode 100644 src/3rdparty/phonon/mmf/videooutput.h create mode 100644 src/3rdparty/phonon/mmf/videooutput_dsa.cpp create mode 100644 src/3rdparty/phonon/mmf/videooutput_dsa.h create mode 100644 src/3rdparty/phonon/mmf/videooutput_surface.cpp create mode 100644 src/3rdparty/phonon/mmf/videooutput_surface.h create mode 100644 src/3rdparty/phonon/mmf/videoplayer_dsa.cpp create mode 100644 src/3rdparty/phonon/mmf/videoplayer_dsa.h create mode 100644 src/3rdparty/phonon/mmf/videoplayer_surface.cpp create mode 100644 src/3rdparty/phonon/mmf/videoplayer_surface.h diff --git a/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp b/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp index 132eb79..6cfeb76 100644 --- a/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp +++ b/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp @@ -20,7 +20,6 @@ along with this library. If not, see . #include "abstractaudioeffect.h" #include "audioplayer.h" -#include "mmf_videoplayer.h" QT_BEGIN_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/abstractaudioeffect.h b/src/3rdparty/phonon/mmf/abstractaudioeffect.h index 436e8e4..d71993b 100644 --- a/src/3rdparty/phonon/mmf/abstractaudioeffect.h +++ b/src/3rdparty/phonon/mmf/abstractaudioeffect.h @@ -28,7 +28,6 @@ along with this library. If not, see . #include "audioplayer.h" #include "effectparameter.h" #include "mmf_medianode.h" -#include "mmf_videoplayer.h" class CMdaAudioOutputStream; diff --git a/src/3rdparty/phonon/mmf/abstractplayer.cpp b/src/3rdparty/phonon/mmf/abstractplayer.cpp index 53973eb..421155b 100644 --- a/src/3rdparty/phonon/mmf/abstractplayer.cpp +++ b/src/3rdparty/phonon/mmf/abstractplayer.cpp @@ -96,7 +96,7 @@ void MMF::AbstractPlayer::volumeChanged(qreal volume) // Video output //----------------------------------------------------------------------------- -void MMF::AbstractPlayer::setVideoOutput(VideoOutput* videoOutput) +void MMF::AbstractPlayer::setVideoOutput(AbstractVideoOutput* videoOutput) { m_videoOutput = videoOutput; videoOutputChanged(); diff --git a/src/3rdparty/phonon/mmf/abstractplayer.h b/src/3rdparty/phonon/mmf/abstractplayer.h index cec5568..92bd87e 100644 --- a/src/3rdparty/phonon/mmf/abstractplayer.h +++ b/src/3rdparty/phonon/mmf/abstractplayer.h @@ -24,7 +24,7 @@ along with this library. If not, see . #include -#include "videooutput.h" +#include "abstractvideooutput.h" class RFile; @@ -34,7 +34,6 @@ namespace Phonon { namespace MMF { -class VideoOutput; /** * @short Interface which abstracts from MediaObject the current @@ -79,7 +78,7 @@ public: virtual void volumeChanged(qreal volume); - void setVideoOutput(VideoOutput* videoOutput); + void setVideoOutput(AbstractVideoOutput *videoOutput); /** * Records error message and changes state to ErrorState @@ -156,7 +155,7 @@ private: protected: // Not owned - VideoOutput* m_videoOutput; + AbstractVideoOutput* m_videoOutput; qreal m_volume; diff --git a/src/3rdparty/phonon/mmf/abstractvideooutput.cpp b/src/3rdparty/phonon/mmf/abstractvideooutput.cpp new file mode 100644 index 0000000..3fe66fc --- /dev/null +++ b/src/3rdparty/phonon/mmf/abstractvideooutput.cpp @@ -0,0 +1,177 @@ +/* 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 . + +*/ + +#include "abstractvideooutput.h" +#include "utils.h" + +#ifndef QT_NO_DEBUG +#include "objectdump.h" +#endif + +#include // for qt_TSize2QSize + +#include +#include + +#include + +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) +{ + +} + +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 visitor(new ObjectDump::QVisitor); + visitor->setPrefix("Phonon::MMF"); // to aid searchability of logs + ObjectDump::addDefaultAnnotators(*visitor); + TRACE("Dumping tree from leaf 0x%08x:", this); + ObjectDump::dumpTreeFromLeaf(*this, *visitor); + + QScopedPointer dumper(new ObjectDump::QDumper); + dumper->setPrefix("Phonon::MMF"); // to aid searchability of logs + ObjectDump::addDefaultAnnotators(*dumper); + TRACE_0("Dumping AbstractVideoOutput:"); + dumper->dumpObject(*this); +#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 . + +*/ + +#ifndef PHONON_MMF_ABSTRACTVIDEOOUTPUT_H +#define PHONON_MMF_ABSTRACTVIDEOOUTPUT_H + +#include +#include +#include +#include "defs.h" + +#include +#include + +#include +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..8cb9db5 --- /dev/null +++ b/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp @@ -0,0 +1,490 @@ +/* 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 . + +*/ + +#include +#include +#include + +#include // 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(); + + 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(RFile &file) +{ + TRAPD(err, m_player->OpenFileL(file)); + return err; +} + +int MMF::AbstractVideoPlayer::openUrl(const QString &url) +{ + TRAPD(err, m_player->OpenUrlL(qt_QString2TPtrC(url))); + return err; +} + +int MMF::AbstractVideoPlayer::bufferStatus() const +{ + int result = 0; + TRAP_IGNORE(m_player->GetVideoLoadingProgressL(result)); + return result; +} + +void MMF::AbstractVideoPlayer::close() +{ + m_player->Close(); +} + +bool MMF::AbstractVideoPlayer::hasVideo() const +{ + return true; +} + +qint64 MMF::AbstractVideoPlayer::currentTime() const +{ + TRACE_CONTEXT(AbstractVideoPlayer::currentTime, 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(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::videoOutputRegionChanged, EVideoInternal); + TRACE_ENTRY("state %d", state()); + + m_window = m_videoOutput ? m_videoOutput->videoWindow() : 0; + + handleVideoWindowChanged(); + + TRACE_EXIT_0(); +} + +void MMF::AbstractVideoPlayer::aspectRatioChanged() +{ + TRACE_CONTEXT(AbstractVideoPlayer::aspectRatioChanged, EVideoInternal); + TRACE_ENTRY("state %d aspectRatio %d", state()); + + updateScaleFactors(m_videoOutput->videoWindowSize()); + + TRACE_EXIT_0(); +} + +void MMF::AbstractVideoPlayer::scaleModeChanged() +{ + TRACE_CONTEXT(AbstractVideoPlayer::scaleModeChanged, EVideoInternal); + TRACE_ENTRY("state %d", state()); + + 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(), 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(), Utils::panic(InvalidStatePanic)); + + TRAPD(err, getVideoClipParametersL(aError)); + + if (KErrNone == err) { + maxVolumeChanged(m_player->MaxVolume()); + + if (m_videoOutput) + m_videoOutput->setVideoSize(m_videoFrameSize); + + prepareCompleted(); + handlePendingParametersChanged(); + + emit totalTimeChanged(totalTime()); + changeState(StoppedState); + } else { + setError(tr("Buffering clip failed"), err); + } + + 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() +{ + 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); + + // Do these after all connections are complete, to ensure + // that any signals generated get to their destinations. + m_videoOutput->winId(); + 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) +{ + 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) + 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 MMF::AbstractVideoPlayer::metaDataEntry(int index) const +{ + CMMFMetaDataEntry *entry = 0; + QT_TRAP_THROWING(entry = m_player->MetaDataEntryL(index)); + return QPair(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..d854793 --- /dev/null +++ b/src/3rdparty/phonon/mmf/abstractvideoplayer.h @@ -0,0 +1,171 @@ +/* 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 . + +*/ + +#ifndef PHONON_MMF_ABSTRACTVIDEOPLAYER_H +#define PHONON_MMF_ABSTRACTVIDEOPLAYER_H + +#include // from epoc32/include + +#include + +#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(RFile &file); + virtual int openUrl(const QString &url); + virtual int bufferStatus() const; + virtual void close(); + + // MediaObjectInterface + virtual bool hasVideo() const; + virtual qint64 currentTime() const; + virtual qint64 totalTime() const; + + // AbstractPlayer + virtual void videoOutputChanged(); + + // AbstractMediaPlayer + virtual int numberOfMetaDataEntries() const; + virtual QPair 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 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 index 18ced94..f0d1be2 100644 --- a/src/3rdparty/phonon/mmf/ancestormovemonitor.cpp +++ b/src/3rdparty/phonon/mmf/ancestormovemonitor.cpp @@ -18,7 +18,8 @@ along with this library. If not, see . #include "ancestormovemonitor.h" #include "utils.h" -#include "videooutput.h" + +#include "videooutput_dsa.h" #include @@ -59,7 +60,7 @@ AncestorMoveMonitor::~AncestorMoveMonitor() // Public functions //----------------------------------------------------------------------------- -void AncestorMoveMonitor::registerTarget(VideoOutput *target) +void AncestorMoveMonitor::registerTarget(DsaVideoOutput *target) { TRACE_CONTEXT(AncestorMoveMonitor::registerTarget, EVideoInternal); TRACE_ENTRY("target 0x%08x", target); @@ -93,7 +94,7 @@ void AncestorMoveMonitor::registerTarget(VideoOutput *target) TRACE_EXIT_0(); } -void AncestorMoveMonitor::unRegisterTarget(VideoOutput *target) +void AncestorMoveMonitor::unRegisterTarget(DsaVideoOutput *target) { TRACE_CONTEXT(AncestorMoveMonitor::unRegisterTarget, EVideoInternal); TRACE_ENTRY("target 0x%08x", target); @@ -126,7 +127,7 @@ bool AncestorMoveMonitor::eventFilter(QObject *watched, QEvent *event) const Hash::const_iterator it = m_hash.find(watched); if(it != m_hash.end()) { const TargetList& targetList = it.value(); - VideoOutput* target = 0; + DsaVideoOutput* target = 0; foreach(target, targetList) { switch (event->type()) { @@ -166,7 +167,7 @@ void AncestorMoveMonitor::dump() const QObject *ancestor = it.key(); TRACE("ancestor 0x%08x", ancestor); const TargetList& targetList = it.value(); - VideoOutput* target = 0; + DsaVideoOutput* target = 0; foreach(target, targetList) { TRACE(" target 0x%08x", target); } @@ -174,7 +175,5 @@ void AncestorMoveMonitor::dump() #endif } - - QT_END_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/ancestormovemonitor.h b/src/3rdparty/phonon/mmf/ancestormovemonitor.h index 0e681aa..f3a022d 100644 --- a/src/3rdparty/phonon/mmf/ancestormovemonitor.h +++ b/src/3rdparty/phonon/mmf/ancestormovemonitor.h @@ -29,7 +29,7 @@ namespace Phonon { namespace MMF { -class VideoOutput; +class DsaVideoOutput; class AncestorMoveMonitor : public QObject { @@ -49,7 +49,7 @@ public: * ancestor list to be updated - therefore it should be called when * the target receives a ParentChange event. */ - void registerTarget(VideoOutput *target); + void registerTarget(DsaVideoOutput *target); /** * Remove target from the monitor. @@ -57,7 +57,7 @@ public: * The target will no longer receive notification when move events are * delivered to its ancestors. */ - void unRegisterTarget(VideoOutput *target); + void unRegisterTarget(DsaVideoOutput *target); protected: /** @@ -77,7 +77,7 @@ private: * therefore a set, however we use QList rather than QSet for * efficiency of iteration. */ - typedef QList TargetList; + typedef QList TargetList; /** * Map from widget on which the move event occurs, to widgets which @@ -92,4 +92,4 @@ private: QT_END_NAMESPACE -#endif +#endif // !PHONON_MMF_ANCESTORMOVEMONITOR_H diff --git a/src/3rdparty/phonon/mmf/backend.cpp b/src/3rdparty/phonon/mmf/backend.cpp index 3568a49..2cec43b 100644 --- a/src/3rdparty/phonon/mmf/backend.cpp +++ b/src/3rdparty/phonon/mmf/backend.cpp @@ -24,7 +24,6 @@ along with this library. If not, see . #include // for TDataType #include "abstractaudioeffect.h" -#include "ancestormovemonitor.h" #include "audiooutput.h" #include "audioplayer.h" #include "backend.h" @@ -44,7 +43,9 @@ using namespace Phonon::MMF; 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); @@ -86,8 +87,15 @@ QObject *Backend::createObject(BackendInterface::Class c, QObject *parent, const static_cast(args.first().toInt()); return m_effectFactory->createAudioEffect(type, parent); } + case VideoWidgetClass: - result = new VideoWidget(m_ancestorMoveMonitor.data(), qobject_cast(parent)); + { + VideoWidget *widget = new VideoWidget(qobject_cast(parent)); +#ifndef PHONON_MMF_VIDEO_SURFACES + widget->setAncestorMoveMonitor(m_ancestorMoveMonitor.data()); +#endif + result = widget; + } break; default: diff --git a/src/3rdparty/phonon/mmf/backend.h b/src/3rdparty/phonon/mmf/backend.h index 9361544..a45c92a 100644 --- a/src/3rdparty/phonon/mmf/backend.h +++ b/src/3rdparty/phonon/mmf/backend.h @@ -19,7 +19,10 @@ along with this library. If not, see . #ifndef PHONON_MMF_BACKEND_H #define PHONON_MMF_BACKEND_H +#ifndef PHONON_MMF_VIDEO_SURFACES #include "ancestormovemonitor.h" +#endif + #include "effectfactory.h" #include @@ -53,7 +56,9 @@ Q_SIGNALS: void objectDescriptionChanged(ObjectDescriptionType); private: +#ifndef PHONON_MMF_VIDEO_SURFACES QScopedPointer m_ancestorMoveMonitor; +#endif QScopedPointer m_effectFactory; }; diff --git a/src/3rdparty/phonon/mmf/defs.h b/src/3rdparty/phonon/mmf/defs.h index 1a93aa9..1ed8250 100644 --- a/src/3rdparty/phonon/mmf/defs.h +++ b/src/3rdparty/phonon/mmf/defs.h @@ -35,6 +35,15 @@ enum MediaType { MediaTypeAudio, MediaTypeVideo }; + +enum VideoParameter { + WindowHandle = 0x1, + WindowScreenRect = 0x2, + ScaleFactors = 0x4 +}; +Q_DECLARE_FLAGS(VideoParameters, VideoParameter) +Q_DECLARE_OPERATORS_FOR_FLAGS(VideoParameters) + } } diff --git a/src/3rdparty/phonon/mmf/mediaobject.cpp b/src/3rdparty/phonon/mmf/mediaobject.cpp index 9744774..ee459e6 100644 --- a/src/3rdparty/phonon/mmf/mediaobject.cpp +++ b/src/3rdparty/phonon/mmf/mediaobject.cpp @@ -22,7 +22,13 @@ along with this library. If not, see . #include "dummyplayer.h" #include "utils.h" #include "utils.h" -#include "mmf_videoplayer.h" + +#ifdef PHONON_MMF_VIDEO_SURFACES +#include "videoplayer_surface.h" +#else +#include "videoplayer_dsa.h" +#endif + #include "videowidget.h" #include "mediaobject.h" @@ -293,7 +299,11 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) break; case MediaTypeVideo: - newPlayer = new VideoPlayer(this, oldPlayer); +#ifdef PHONON_MMF_VIDEO_SURFACES + newPlayer = SurfaceVideoPlayer::create(this, oldPlayer); +#else + newPlayer = DsaVideoPlayer::create(this, oldPlayer); +#endif break; } @@ -383,7 +393,7 @@ void MMF::MediaObject::disconnectMediaObject(MediaObject * /*mediaObject*/) // Video output //----------------------------------------------------------------------------- -void MMF::MediaObject::setVideoOutput(VideoOutput* videoOutput) +void MMF::MediaObject::setVideoOutput(AbstractVideoOutput* videoOutput) { m_player->setVideoOutput(videoOutput); } diff --git a/src/3rdparty/phonon/mmf/mediaobject.h b/src/3rdparty/phonon/mmf/mediaobject.h index d6248e2..62e0a0e 100644 --- a/src/3rdparty/phonon/mmf/mediaobject.h +++ b/src/3rdparty/phonon/mmf/mediaobject.h @@ -38,7 +38,7 @@ namespace Phonon namespace MMF { class AbstractPlayer; -class VideoOutput; +class AbstractVideoOutput; /** * @short Facade class which wraps MMF client utility instance @@ -85,7 +85,7 @@ public: */ AbstractPlayer *abstractPlayer() const; - void setVideoOutput(VideoOutput* videoOutput); + void setVideoOutput(AbstractVideoOutput* videoOutput); public Q_SLOTS: void volumeChanged(qreal volume); diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp deleted file mode 100644 index 127edb4..0000000 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp +++ /dev/null @@ -1,658 +0,0 @@ -/* 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 . - -*/ - -#include // for QApplication::activeWindow -#include -#include -#include - -#include // for CCoeEnv -#include - -#include "mmf_videoplayer.h" -#include "utils.h" - -#ifndef QT_NO_DEBUG -#include "objectdump.h" -#endif - -QT_BEGIN_NAMESPACE - -using namespace Phonon; -using namespace Phonon::MMF; - -/*! \class MMF::VideoPlayer - \internal -*/ - -//----------------------------------------------------------------------------- -// Constructor / destructor -//----------------------------------------------------------------------------- - -MMF::VideoPlayer::VideoPlayer(MediaObject *parent, const AbstractPlayer *player) - : AbstractMediaPlayer(parent, player) - , m_wsSession(CCoeEnv::Static()->WsSession()) - , m_screenDevice(*CCoeEnv::Static()->ScreenDevice()) - , m_window(0) - , m_totalTime(0) - , m_pendingChanges(false) - , m_dsaActive(false) -{ - construct(); -} - -void MMF::VideoPlayer::construct() -{ - TRACE_CONTEXT(VideoPlayer::VideoPlayer, EVideoApi); - TRACE_ENTRY_0(); - - getVideoWindow(); - - 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_videoRect, m_videoRect - ) - ); - m_player.reset(player); - - // CVideoPlayerUtility::NewL starts DSA - m_dsaActive = true; - - m_player->RegisterForVideoLoadingNotification(*this); - - TRACE_EXIT_0(); -} - -MMF::VideoPlayer::~VideoPlayer() -{ - TRACE_CONTEXT(VideoPlayer::~VideoPlayer, 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::VideoPlayer::nativePlayer() const -{ - return m_player.data(); -} - -//----------------------------------------------------------------------------- -// Public API -//----------------------------------------------------------------------------- - -void MMF::VideoPlayer::doPlay() -{ - TRACE_CONTEXT(VideoPlayer::doPlay, EVideoApi); - - applyPendingChanges(); - - m_player->Play(); -} - -void MMF::VideoPlayer::doPause() -{ - TRACE_CONTEXT(VideoPlayer::doPause, EVideoApi); - - TRAPD(err, m_player->PauseL()); - if (KErrNone != err && state() != ErrorState) { - TRACE("PauseL error %d", err); - setError(tr("Pause failed"), err); - } -} - -void MMF::VideoPlayer::doStop() -{ - m_player->Stop(); -} - -void MMF::VideoPlayer::doSeek(qint64 ms) -{ - TRACE_CONTEXT(VideoPlayer::doSeek, EVideoApi); - - TRAPD(err, m_player->SetPositionL(TTimeIntervalMicroSeconds(ms * 1000))); - - if(KErrNone != err) - setError(tr("Seek failed"), err); -} - -int MMF::VideoPlayer::setDeviceVolume(int mmfVolume) -{ - TRAPD(err, m_player->SetVolumeL(mmfVolume)); - return err; -} - -int MMF::VideoPlayer::openFile(RFile& file) -{ - TRAPD(err, m_player->OpenFileL(file)); - return err; -} - -int MMF::VideoPlayer::openUrl(const QString& url) -{ - TRAPD(err, m_player->OpenUrlL(qt_QString2TPtrC(url))); - return err; -} - -int MMF::VideoPlayer::bufferStatus() const -{ - int result = 0; - TRAP_IGNORE(m_player->GetVideoLoadingProgressL(result)); - return result; -} - -void MMF::VideoPlayer::close() -{ - m_player->Close(); -} - -bool MMF::VideoPlayer::hasVideo() const -{ - return true; -} - -qint64 MMF::VideoPlayer::currentTime() const -{ - TRACE_CONTEXT(VideoPlayer::currentTime, 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(this)->setError(tr("Getting position failed"), err); - } - - return result; -} - -qint64 MMF::VideoPlayer::totalTime() const -{ - return m_totalTime; -} - - -//----------------------------------------------------------------------------- -// MVideoPlayerUtilityObserver callbacks -//----------------------------------------------------------------------------- - -void MMF::VideoPlayer::MvpuoOpenComplete(TInt aError) -{ - TRACE_CONTEXT(VideoPlayer::MvpuoOpenComplete, EVideoApi); - TRACE_ENTRY("state %d error %d", state(), aError); - - __ASSERT_ALWAYS(LoadingState == state(), Utils::panic(InvalidStatePanic)); - - if (KErrNone == aError) - m_player->Prepare(); - else - setError(tr("Opening clip failed"), aError); - - TRACE_EXIT_0(); -} - -void MMF::VideoPlayer::MvpuoPrepareComplete(TInt aError) -{ - TRACE_CONTEXT(VideoPlayer::MvpuoPrepareComplete, EVideoApi); - TRACE_ENTRY("state %d error %d", state(), aError); - - __ASSERT_ALWAYS(LoadingState == state(), Utils::panic(InvalidStatePanic)); - - TRAPD(err, doPrepareCompleteL(aError)); - - if (KErrNone == err) { - maxVolumeChanged(m_player->MaxVolume()); - - if (m_videoOutput) - m_videoOutput->setVideoSize(m_videoFrameSize); - - updateVideoRect(); - applyPendingChanges(); - - emit totalTimeChanged(totalTime()); - changeState(StoppedState); - } else { - setError(tr("Buffering clip failed"), err); - } - - TRACE_EXIT_0(); -} - -void MMF::VideoPlayer::doPrepareCompleteL(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::VideoPlayer::MvpuoFrameReady(CFbsBitmap &aFrame, TInt aError) -{ - TRACE_CONTEXT(VideoPlayer::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::VideoPlayer::MvpuoPlayComplete(TInt aError) -{ - TRACE_CONTEXT(VideoPlayer::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::VideoPlayer::MvpuoEvent(const TMMFEvent &aEvent) -{ - TRACE_CONTEXT(VideoPlayer::MvpuoEvent, EVideoApi); - TRACE_ENTRY("state %d", state()); - - Q_UNUSED(aEvent); - - TRACE_EXIT_0(); -} - - -//----------------------------------------------------------------------------- -// MVideoLoadingObserver callbacks -//----------------------------------------------------------------------------- - -void MMF::VideoPlayer::MvloLoadingStarted() -{ - bufferingStarted(); -} - -void MMF::VideoPlayer::MvloLoadingComplete() -{ - bufferingComplete(); -} - - -//----------------------------------------------------------------------------- -// Video window updates -//----------------------------------------------------------------------------- - -void MMF::VideoPlayer::getVideoWindow() -{ - TRACE_CONTEXT(VideoPlayer::getVideoWindow, EVideoInternal); - TRACE_ENTRY_0(); - - if(m_videoOutput) { - // Dump information to log, only in debug builds - m_videoOutput->dump(); - - initVideoOutput(); - videoWindowChanged(); - } else - // Top-level window - m_window = QApplication::activeWindow()->effectiveWinId()->DrawableWindow(); - - TRACE_EXIT_0(); -} - -void MMF::VideoPlayer::videoOutputChanged() -{ - TRACE_CONTEXT(VideoPlayer::videoOutputChanged, EVideoInternal); - TRACE_ENTRY_0(); - - if (m_videoOutput) { - initVideoOutput(); - videoWindowChanged(); - } - - TRACE_EXIT_0(); -} - -void MMF::VideoPlayer::initVideoOutput() -{ - m_videoOutput->winId(); - m_videoOutput->setVideoSize(m_videoFrameSize); - - bool connected = connect( - m_videoOutput, SIGNAL(videoWindowChanged()), - this, SLOT(videoWindowChanged()) - ); - 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); - - 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); -} - -void MMF::VideoPlayer::videoWindowChanged() -{ - TRACE_CONTEXT(VideoPlayer::videoOutputRegionChanged, EVideoInternal); - TRACE_ENTRY("state %d", state()); - - m_window = m_videoOutput->videoWindow(); - updateVideoRect(); - - TRACE_EXIT_0(); -} - -void MMF::VideoPlayer::suspendDirectScreenAccess() -{ - m_dsaWasActive = stopDirectScreenAccess(); -} - -void MMF::VideoPlayer::resumeDirectScreenAccess() -{ - if(m_dsaWasActive) { - startDirectScreenAccess(); - m_dsaWasActive = false; - } -} - -void MMF::VideoPlayer::startDirectScreenAccess() -{ - if(!m_dsaActive) { - TRAPD(err, m_player->StartDirectScreenAccessL()); - if(KErrNone == err) - m_dsaActive = true; - else - setError(tr("Video display error"), err); - } -} - -bool MMF::VideoPlayer::stopDirectScreenAccess() -{ - const bool dsaWasActive = m_dsaActive; - if(m_dsaActive) { - TRAPD(err, m_player->StopDirectScreenAccessL()); - if(KErrNone == err) - m_dsaActive = false; - else - setError(tr("Video display error"), err); - } - return dsaWasActive; -} - -// 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::VideoPlayer::updateVideoRect() -{ - QRect videoRect; - QRect windowRect = m_videoOutput->videoWindowRect(); - - // 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); - - const QSize windowSize = windowRect.size(); - - // 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(); - - m_videoRect = qt_QRect2TRect(windowRect); - - if (state() == LoadingState) - m_pendingChanges = true; - else { - applyVideoWindowChange(); - m_pendingChanges = false; - } -} - -void MMF::VideoPlayer::aspectRatioChanged() -{ - TRACE_CONTEXT(VideoPlayer::aspectRatioChanged, EVideoInternal); - TRACE_ENTRY("state %d aspectRatio %d", state()); - - updateVideoRect(); - - TRACE_EXIT_0(); -} - -void MMF::VideoPlayer::scaleModeChanged() -{ - TRACE_CONTEXT(VideoPlayer::scaleModeChanged, EVideoInternal); - TRACE_ENTRY("state %d", state()); - - updateVideoRect(); - - TRACE_EXIT_0(); -} - -#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) -{ - 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; iCount(); ++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 // _DEBUG - -void MMF::VideoPlayer::applyPendingChanges() -{ - if(m_pendingChanges) - applyVideoWindowChange(); - - m_pendingChanges = false; -} - -void MMF::VideoPlayer::applyVideoWindowChange() -{ - TRACE_CONTEXT(VideoPlayer::applyVideoWindowChange, EVideoInternal); - TRACE_ENTRY_0(); - -#ifndef QT_NO_DEBUG - getDsaRegion(m_wsSession, *m_window); -#endif - - static const TBool antialias = ETrue; - - TRAPD(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) { - TRAP(err, - m_player->SetDisplayWindowL - ( - m_wsSession, m_screenDevice, - *m_window, - m_videoRect, m_videoRect - ) - ); - - if (KErrNone != err) { - TRACE("SetDisplayWindowL err %d", err); - setError(tr("Video display error"), err); - } else { - m_dsaActive = true; - 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(); -} - - -//----------------------------------------------------------------------------- -// Metadata -//----------------------------------------------------------------------------- - -int MMF::VideoPlayer::numberOfMetaDataEntries() const -{ - int numberOfEntries = 0; - TRAP_IGNORE(numberOfEntries = m_player->NumberOfMetaDataEntriesL()); - return numberOfEntries; -} - -QPair MMF::VideoPlayer::metaDataEntry(int index) const -{ - CMMFMetaDataEntry *entry = 0; - QT_TRAP_THROWING(entry = m_player->MetaDataEntryL(index)); - return QPair(qt_TDesC2QString(entry->Name()), qt_TDesC2QString(entry->Value())); -} - -QT_END_NAMESPACE - diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.h b/src/3rdparty/phonon/mmf/mmf_videoplayer.h deleted file mode 100644 index 0253ab9..0000000 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.h +++ /dev/null @@ -1,138 +0,0 @@ -/* 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 . - -*/ - -#ifndef PHONON_MMF_VIDEOPLAYER_H -#define PHONON_MMF_VIDEOPLAYER_H - -#include // from epoc32/include - -#include "abstractmediaplayer.h" -#include "videooutput.h" - -QT_BEGIN_NAMESPACE - -namespace Phonon -{ -namespace MMF -{ -/** - * @short Wrapper over MMF video client utility - * - * See - * How to - * play a video file using CVideoPlayerUtility - */ -class VideoPlayer : public AbstractMediaPlayer - , public MVideoPlayerUtilityObserver - , public MVideoLoadingObserver -{ - Q_OBJECT - -public: - VideoPlayer(MediaObject *parent = 0, const AbstractPlayer *player = 0); - virtual ~VideoPlayer(); - - 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(RFile& file); - virtual int openUrl(const QString& url); - virtual int bufferStatus() const; - virtual void close(); - - // MediaObjectInterface - virtual bool hasVideo() const; - virtual qint64 currentTime() const; - virtual qint64 totalTime() const; - - // AbstractPlayer - virtual void videoOutputChanged(); - - // AbstractMediaPlayer - virtual int numberOfMetaDataEntries() const; - virtual QPair metaDataEntry(int index) const; - -public Q_SLOTS: - void videoWindowChanged(); - void aspectRatioChanged(); - void scaleModeChanged(); - void suspendDirectScreenAccess(); - void resumeDirectScreenAccess(); - -private: - void construct(); - - void doPrepareCompleteL(TInt aError); - - void getVideoWindow(); - void initVideoOutput(); - void updateVideoRect(); - - void applyPendingChanges(); - void applyVideoWindowChange(); - - void startDirectScreenAccess(); - bool stopDirectScreenAccess(); - -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(); - -private: - QScopedPointer m_player; - - // Not owned - RWsSession& m_wsSession; - CWsScreenDevice& m_screenDevice; - RWindowBase* m_window; - - /* Extent of the video display - will be clipped to m_windowRect */ - TRect m_videoRect; - - TReal32 m_scaleWidth; - TReal32 m_scaleHeight; - - QSize m_videoFrameSize; - qint64 m_totalTime; - - bool m_pendingChanges; - bool m_dsaActive; - bool m_dsaWasActive; - -}; - -} -} - -QT_END_NAMESPACE - -#endif diff --git a/src/3rdparty/phonon/mmf/videooutput.cpp b/src/3rdparty/phonon/mmf/videooutput.cpp deleted file mode 100644 index 119dcb1..0000000 --- a/src/3rdparty/phonon/mmf/videooutput.cpp +++ /dev/null @@ -1,303 +0,0 @@ -/* 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 . - -*/ - -#include "ancestormovemonitor.h" -#include "utils.h" -#include "videooutput.h" - -#ifndef QT_NO_DEBUG -#include "objectdump.h" -#endif - -#include -#include -#include -#include - -#include // for qt_TRect2QRect -#include // to access QWExtra - -#include - -#include // for CCoeEnv - -QT_BEGIN_NAMESPACE - -using namespace Phonon; -using namespace Phonon::MMF; - -/*! \class MMF::VideoOutput - \internal -*/ - -//----------------------------------------------------------------------------- -// Constants -//----------------------------------------------------------------------------- - -static const Phonon::VideoWidget::AspectRatio DefaultAspectRatio = - Phonon::VideoWidget::AspectRatioAuto; -static const Phonon::VideoWidget::ScaleMode DefaultScaleMode = - Phonon::VideoWidget::FitInView; - - -//----------------------------------------------------------------------------- -// Constructor / destructor -//----------------------------------------------------------------------------- - -MMF::VideoOutput::VideoOutput - (AncestorMoveMonitor* ancestorMoveMonitor, QWidget* parent) - : QWidget(parent) - , m_ancestorMoveMonitor(ancestorMoveMonitor) - , m_aspectRatio(DefaultAspectRatio) - , m_scaleMode(DefaultScaleMode) -{ - TRACE_CONTEXT(VideoOutput::VideoOutput, 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; - - getVideoWindowRect(); - registerForAncestorMoved(); - - dump(); - - TRACE_EXIT_0(); -} - -MMF::VideoOutput::~VideoOutput() -{ - TRACE_CONTEXT(VideoOutput::~VideoOutput, EVideoInternal); - TRACE_ENTRY_0(); - - m_ancestorMoveMonitor->unRegisterTarget(this); - - TRACE_EXIT_0(); -} - -void MMF::VideoOutput::setVideoSize(const QSize& frameSize) -{ - TRACE_CONTEXT(VideoOutput::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(); - } -} - -void MMF::VideoOutput::ancestorMoved() -{ - TRACE_CONTEXT(VideoOutput::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_videoWindowRect.topLeft()) { - m_videoWindowRect.moveTo(newWindowPos); - emit videoWindowChanged(); - } - } - - TRACE_EXIT_0(); -} - -//----------------------------------------------------------------------------- -// QWidget -//----------------------------------------------------------------------------- - -QSize MMF::VideoOutput::sizeHint() const -{ - // TODO: replace this with a more sensible default - QSize result(320, 240); - - if (!m_videoFrameSize.isNull()) - result = m_videoFrameSize; - - return result; -} - -void MMF::VideoOutput::paintEvent(QPaintEvent* event) -{ - TRACE_CONTEXT(VideoOutput::paintEvent, EVideoInternal); - TRACE("rect %d %d - %d %d", - event->rect().left(), event->rect().top(), - event->rect().right(), event->rect().bottom()); - TRACE("regions %d", event->region().rectCount()); - TRACE("type %d", event->type()); - - // Do nothing -} - -void MMF::VideoOutput::resizeEvent(QResizeEvent* event) -{ - TRACE_CONTEXT(VideoOutput::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_videoWindowRect.setSize(event->size()); - emit videoWindowChanged(); - } -} - -void MMF::VideoOutput::moveEvent(QMoveEvent* event) -{ - TRACE_CONTEXT(VideoOutput::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_videoWindowRect.moveTo(event->pos()); - emit videoWindowChanged(); - } -} - -bool MMF::VideoOutput::event(QEvent* event) -{ - TRACE_CONTEXT(VideoOutput::event, EVideoInternal); - - if (event->type() == QEvent::WinIdChange) { - TRACE_0("WinIdChange"); - getVideoWindowRect(); - 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); -} - - -//----------------------------------------------------------------------------- -// Public functions -//----------------------------------------------------------------------------- - -RWindowBase* MMF::VideoOutput::videoWindow() -{ - CCoeControl *control = internalWinId(); - if(!control) - control = effectiveWinId(); - - RWindowBase *window = 0; - if(control) - window = control->DrawableWindow(); - - return window; -} - -const QRect& MMF::VideoOutput::videoWindowRect() const -{ - return m_videoWindowRect; -} - -Phonon::VideoWidget::AspectRatio MMF::VideoOutput::aspectRatio() const -{ - return m_aspectRatio; -} - -void MMF::VideoOutput::setAspectRatio - (Phonon::VideoWidget::AspectRatio aspectRatio) -{ - if(m_aspectRatio != aspectRatio) { - m_aspectRatio = aspectRatio; - emit aspectRatioChanged(); - } -} - -Phonon::VideoWidget::ScaleMode MMF::VideoOutput::scaleMode() const -{ - return m_scaleMode; -} - -void MMF::VideoOutput::setScaleMode - (Phonon::VideoWidget::ScaleMode scaleMode) -{ - if(m_scaleMode != scaleMode) { - m_scaleMode = scaleMode; - emit scaleModeChanged(); - } -} - - -//----------------------------------------------------------------------------- -// Private functions -//----------------------------------------------------------------------------- - -void MMF::VideoOutput::getVideoWindowRect() -{ - RWindowBase *const window = videoWindow(); - if(window) - m_videoWindowRect = - qt_TRect2QRect(TRect(window->AbsPosition(), window->Size())); -} - -void MMF::VideoOutput::registerForAncestorMoved() -{ - m_ancestorMoveMonitor->registerTarget(this); -} - -void MMF::VideoOutput::dump() const -{ -#ifndef QT_NO_DEBUG - TRACE_CONTEXT(VideoOutput::dump, EVideoInternal); - - QScopedPointer visitor(new ObjectDump::QVisitor); - visitor->setPrefix("Phonon::MMF"); // to aid searchability of logs - ObjectDump::addDefaultAnnotators(*visitor); - TRACE("Dumping tree from leaf 0x%08x:", this); - ObjectDump::dumpTreeFromLeaf(*this, *visitor); - - QScopedPointer dumper(new ObjectDump::QDumper); - dumper->setPrefix("Phonon::MMF"); // to aid searchability of logs - ObjectDump::addDefaultAnnotators(*dumper); - TRACE_0("Dumping VideoOutput:"); - dumper->dumpObject(*this); -#endif -} - -void MMF::VideoOutput::beginNativePaintEvent(const QRect& /*controlRect*/) -{ - emit beginVideoWindowNativePaint(); -} - -void MMF::VideoOutput::endNativePaintEvent(const QRect& /*controlRect*/) -{ - // Ensure that draw ops are executed into the WSERV output framebuffer - CCoeEnv::Static()->WsSession().Flush(); - - emit endVideoWindowNativePaint(); -} - -QT_END_NAMESPACE - diff --git a/src/3rdparty/phonon/mmf/videooutput.h b/src/3rdparty/phonon/mmf/videooutput.h deleted file mode 100644 index 3e9c036..0000000 --- a/src/3rdparty/phonon/mmf/videooutput.h +++ /dev/null @@ -1,105 +0,0 @@ -/* 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 . - -*/ - -#ifndef PHONON_MMF_VIDEOOUTPUT_H -#define PHONON_MMF_VIDEOOUTPUT_H - -#include -#include -#include -#include "defs.h" - -#include - -#include -class RWindowBase; - -QT_BEGIN_NAMESPACE - -namespace Phonon -{ -namespace MMF -{ -class AncestorMoveMonitor; - -class VideoOutput : public QWidget -{ - Q_OBJECT - -public: - VideoOutput(AncestorMoveMonitor* ancestorMoveMonitor, QWidget* parent); - ~VideoOutput(); - - // Set size of video frame. Called by VideoPlayer. - void setVideoSize(const QSize& size); - - RWindowBase* videoWindow(); - const QRect& videoWindowRect() const; - - Phonon::VideoWidget::AspectRatio aspectRatio() const; - void setAspectRatio(Phonon::VideoWidget::AspectRatio aspectRatio); - - Phonon::VideoWidget::ScaleMode scaleMode() const; - void setScaleMode(Phonon::VideoWidget::ScaleMode scaleMode); - - // Called by AncestorMoveMonitor - void ancestorMoved(); - - // Debugging output - void dump() const; - -public Q_SLOTS: - void beginNativePaintEvent(const QRect& /*controlRect*/); - void endNativePaintEvent(const QRect& /*controlRect*/); - -Q_SIGNALS: - void videoWindowChanged(); - void aspectRatioChanged(); - void scaleModeChanged(); - void beginVideoWindowNativePaint(); - void endVideoWindowNativePaint(); - -protected: - // Override QWidget functions - QSize sizeHint() const; - void paintEvent(QPaintEvent* event); - void resizeEvent(QResizeEvent* event); - void moveEvent(QMoveEvent* event); - bool event(QEvent* event); - -private: - void getVideoWindowRect(); - void registerForAncestorMoved(); - -private: - // Not owned - AncestorMoveMonitor* m_ancestorMoveMonitor; - - QSize m_videoFrameSize; - QRect m_videoWindowRect; - - Phonon::VideoWidget::AspectRatio m_aspectRatio; - Phonon::VideoWidget::ScaleMode m_scaleMode; - -}; -} -} - -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..a5e2ac8 --- /dev/null +++ b/src/3rdparty/phonon/mmf/videooutput_dsa.cpp @@ -0,0 +1,177 @@ +/* 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 . + +*/ + +#include // for qt_TRect2QRect +#include // to access QWExtra +#include +#include + +#include // 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*/) +{ + emit beginVideoWindowNativePaint(); +} + +void MMF::DsaVideoOutput::endNativePaintEvent(const QRect & /*controlRect*/) +{ + // 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 . + +*/ + +#ifndef PHONON_MMF_VIDEOOUTPUT_DSA_H +#define PHONON_MMF_VIDEOOUTPUT_DSA_H + +#include + +#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 . + +*/ + +#include + +#include // for qt_TRect2QRect +#include // 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..0b22a710 --- /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 . + +*/ + +#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..21cdb16 --- /dev/null +++ b/src/3rdparty/phonon/mmf/videoplayer_dsa.cpp @@ -0,0 +1,285 @@ +/* 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 . + +*/ + +#include // for CCoeControl + +#include // for QApplication::activeWindow +#include // 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 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() +{ + QRect windowRect = static_cast(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; + + m_player->RegisterForVideoLoadingNotification(*this); +} + +void MMF::DsaVideoPlayer::initVideoOutput() +{ + 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() +{ + videoWindowScreenRectChanged(); +} + +void MMF::DsaVideoPlayer::handleVideoWindowChanged() +{ + if (!m_window) { + m_window = QApplication::activeWindow()->effectiveWinId()->DrawableWindow(); + 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) +{ + 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; iCount(); ++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_0(); + +#ifndef QT_NO_DEBUG + getDsaRegion(m_wsSession, *m_window); +#endif + + 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() +{ + if (!m_dsaActive) { + TRAPD(err, m_player->StartDirectScreenAccessL()); + if (KErrNone == err) + m_dsaActive = true; + else + setError(tr("Video display error"), err); + } +} + +bool MMF::DsaVideoPlayer::stopDirectScreenAccess() +{ + const bool dsaWasActive = m_dsaActive; + if (m_dsaActive) { + TRAPD(err, m_player->StopDirectScreenAccessL()); + if (KErrNone == err) + m_dsaActive = false; + else + setError(tr("Video display error"), 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 . + +*/ + +#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..5f234e5 --- /dev/null +++ b/src/3rdparty/phonon/mmf/videoplayer_surface.cpp @@ -0,0 +1,150 @@ +/* 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 . + +*/ + +#include + +#include // 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 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() +{ + 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() +{ + 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) +{ + CVideoPlayerUtility2 *player = static_cast(m_player.data()); + + int err = KErrNone; + + TRect rect; + + if (m_videoOutput) { + m_videoOutput->dump(); + const QSize size = m_videoOutput->videoWindowSize(); + rect.SetSize(TSize(size.width(), size.height())); + } + + if (parameters & WindowHandle) { + if (m_displayWindow) + player->RemoveDisplayWindow(*m_displayWindow); + + RWindow *window = static_cast(m_window); + if (window) { + window->SetBackgroundColor(TRgb(0, 0, 0, 255)); + TRAP(err, player->AddDisplayWindowL(m_wsSession, m_screenDevice, *window, rect, rect)); + if (KErrNone != err) { + setError(tr("Video display error"), err); + window = 0; + } + } + m_displayWindow = window; + } + + if (KErrNone == err) { + if (parameters & ScaleFactors) { + 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); + } + } +} + +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..c05da9c --- /dev/null +++ b/src/3rdparty/phonon/mmf/videoplayer_surface.h @@ -0,0 +1,78 @@ +/* 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 . + +*/ + +#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); + +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 index bc9acfd..4ed9979 100644 --- a/src/3rdparty/phonon/mmf/videowidget.cpp +++ b/src/3rdparty/phonon/mmf/videowidget.cpp @@ -18,10 +18,15 @@ along with this library. If not, see . #include "mediaobject.h" #include "utils.h" -#include "videooutput.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; @@ -45,10 +50,13 @@ static const qreal DefaultSaturation = 1.0; // Constructor / destructor //----------------------------------------------------------------------------- -MMF::VideoWidget::VideoWidget - (AncestorMoveMonitor* ancestorMoveMonitor, QWidget* parent) +MMF::VideoWidget::VideoWidget(QWidget *parent) : MediaNode(parent) - , m_videoOutput(new VideoOutput(ancestorMoveMonitor, 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) @@ -68,6 +76,13 @@ MMF::VideoWidget::~VideoWidget() TRACE_EXIT_0(); } +#ifndef PHONON_MMF_VIDEO_SURFACES +void MMF::VideoWidget::setAncestorMoveMonitor(AncestorMoveMonitor *monitor) +{ + static_cast(m_videoOutput.data())->setAncestorMoveMonitor(monitor); +} +#endif + //----------------------------------------------------------------------------- // VideoWidgetInterface diff --git a/src/3rdparty/phonon/mmf/videowidget.h b/src/3rdparty/phonon/mmf/videowidget.h index 899dca6..3b6283e 100644 --- a/src/3rdparty/phonon/mmf/videowidget.h +++ b/src/3rdparty/phonon/mmf/videowidget.h @@ -19,8 +19,8 @@ along with this library. If not, see . #ifndef PHONON_MMF_VIDEOWIDGET_H #define PHONON_MMF_VIDEOWIDGET_H +#include "abstractvideooutput.h" #include "mmf_medianode.h" -#include "videooutput.h" #include #include @@ -32,8 +32,9 @@ namespace Phonon { namespace MMF { +#ifndef PHONON_MMF_VIDEO_SURFACES class AncestorMoveMonitor; -class VideoOutput; +#endif class VideoWidget : public MediaNode , public Phonon::VideoWidgetInterface @@ -42,9 +43,13 @@ class VideoWidget : public MediaNode Q_INTERFACES(Phonon::VideoWidgetInterface) public: - VideoWidget(AncestorMoveMonitor* ancestorMoveMonitor, QWidget* parent); + 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); @@ -66,7 +71,7 @@ protected: void disconnectMediaObject(MediaObject *mediaObject); private: - QScopedPointer m_videoOutput; + QScopedPointer m_videoOutput; qreal m_brightness; qreal m_contrast; diff --git a/src/plugins/phonon/mmf/mmf.pro b/src/plugins/phonon/mmf/mmf.pro index cfaca9d..da41f18 100644 --- a/src/plugins/phonon/mmf/mmf.pro +++ b/src/plugins/phonon/mmf/mmf.pro @@ -20,13 +20,16 @@ phonon_mmf_audio_drm { # '#include ' picks up the Symbian header, as intended. PREPEND_INCLUDEPATH = /epoc32/include +PREPEND_INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty + INCLUDEPATH += $$MW_LAYER_SYSTEMINCLUDE HEADERS += \ $$PHONON_MMF_DIR/abstractaudioeffect.h \ $$PHONON_MMF_DIR/abstractmediaplayer.h \ $$PHONON_MMF_DIR/abstractplayer.h \ - $$PHONON_MMF_DIR/ancestormovemonitor.h \ + $$PHONON_MMF_DIR/abstractvideooutput.h \ + $$PHONON_MMF_DIR/abstractvideoplayer.h \ $$PHONON_MMF_DIR/audioequalizer.h \ $$PHONON_MMF_DIR/audiooutput.h \ $$PHONON_MMF_DIR/audioplayer.h \ @@ -40,23 +43,22 @@ HEADERS += \ $$PHONON_MMF_DIR/loudness.h \ $$PHONON_MMF_DIR/mediaobject.h \ $$PHONON_MMF_DIR/mmf_medianode.h \ - $$PHONON_MMF_DIR/mmf_videoplayer.h \ $$PHONON_MMF_DIR/stereowidening.h \ $$PHONON_MMF_DIR/objectdump.h \ $$PHONON_MMF_DIR/objectdump_symbian.h \ $$PHONON_MMF_DIR/objecttree.h \ $$PHONON_MMF_DIR/utils.h \ - $$PHONON_MMF_DIR/videooutput.h \ $$PHONON_MMF_DIR/videowidget.h SOURCES += \ $$PHONON_MMF_DIR/abstractaudioeffect.cpp \ $$PHONON_MMF_DIR/abstractmediaplayer.cpp \ $$PHONON_MMF_DIR/abstractplayer.cpp \ - $$PHONON_MMF_DIR/ancestormovemonitor.cpp \ $$PHONON_MMF_DIR/audioequalizer.cpp \ $$PHONON_MMF_DIR/audiooutput.cpp \ $$PHONON_MMF_DIR/audioplayer.cpp \ + $$PHONON_MMF_DIR/abstractvideooutput.cpp \ + $$PHONON_MMF_DIR/abstractvideoplayer.cpp \ $$PHONON_MMF_DIR/backend.cpp \ $$PHONON_MMF_DIR/bassboost.cpp \ $$PHONON_MMF_DIR/dummyplayer.cpp \ @@ -66,15 +68,34 @@ SOURCES += \ $$PHONON_MMF_DIR/loudness.cpp \ $$PHONON_MMF_DIR/mediaobject.cpp \ $$PHONON_MMF_DIR/mmf_medianode.cpp \ - $$PHONON_MMF_DIR/mmf_videoplayer.cpp \ $$PHONON_MMF_DIR/stereowidening.cpp \ $$PHONON_MMF_DIR/objectdump.cpp \ $$PHONON_MMF_DIR/objectdump_symbian.cpp \ $$PHONON_MMF_DIR/objecttree.cpp \ $$PHONON_MMF_DIR/utils.cpp \ - $$PHONON_MMF_DIR/videooutput.cpp \ $$PHONON_MMF_DIR/videowidget.cpp +# 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 \ +} + LIBS += -lcone LIBS += -lws32 -- cgit v0.12 From 47b1a3853d76a5abc5f32b02ccd1d83df3aa601a Mon Sep 17 00:00:00 2001 From: Jason Barron Date: Thu, 18 Mar 2010 16:10:51 +0100 Subject: Initialize the graphics system before creating the style. Previously if the style was creating any pixmaps they were going to the createDefaultPixmapData() function which creates a default platform pixmap without considering the graphics system. If these pixmaps are used they may end up going through a suboptimal code path because they are not the same type of pixmap that is expected by the graphics system. The fix here is to intialize the graphics system before the style is created. Reviewed-by: Trond --- src/gui/kernel/qapplication.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 4fe3900..e480696 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -892,6 +892,14 @@ void QApplicationPrivate::initialize() { QWidgetPrivate::mapper = new QWidgetMapper; QWidgetPrivate::allWidgets = new QWidgetSet; + +#if !defined(Q_WS_X11) && !defined(Q_WS_QWS) + // initialize the graphics system - on X11 this is initialized inside + // qt_init() in qapplication_x11.cpp because of several reasons. + // On QWS, the graphics system is set by the QScreen plugin. + graphics_system = QGraphicsSystemFactory::create(graphics_system_name); +#endif + if (qt_appType != QApplication::Tty) (void) QApplication::style(); // trigger creation of application style // trigger registering of QVariant's GUI types @@ -926,12 +934,6 @@ void QApplicationPrivate::initialize() // Set up which span functions should be used in raster engine... qInitDrawhelperAsm(); -#if !defined(Q_WS_X11) && !defined(Q_WS_QWS) - // initialize the graphics system - on X11 this is initialized inside - // qt_init() in qapplication_x11.cpp because of several reasons. - // On QWS, the graphics system is set by the QScreen plugin. - graphics_system = QGraphicsSystemFactory::create(graphics_system_name); -#endif #ifndef QT_NO_WHEELEVENT QApplicationPrivate::wheel_scroll_lines = 3; #endif -- cgit v0.12