diff options
author | Alan Alpert <alan.alpert@nokia.com> | 2010-03-23 11:29:00 (GMT) |
---|---|---|
committer | Alan Alpert <alan.alpert@nokia.com> | 2010-03-23 11:29:00 (GMT) |
commit | 56939d84ed5303dbc1b3926d1d5ae50d6512961e (patch) | |
tree | 84d3ed8ca7dacd6f57598c118e8972f592abf08a /src/3rdparty/phonon/mmf/videoplayer_dsa.cpp | |
parent | 90e401d350a75dfa365a8f3090514a2741f7bef6 (diff) | |
parent | 99788a16e70a36f5d1b525414829040aa808908a (diff) | |
download | Qt-56939d84ed5303dbc1b3926d1d5ae50d6512961e.zip Qt-56939d84ed5303dbc1b3926d1d5ae50d6512961e.tar.gz Qt-56939d84ed5303dbc1b3926d1d5ae50d6512961e.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-qml into 4.7
Conflicts:
tests/auto/declarative/qdeclarativedom/data/importlib/sublib/qmldir
Diffstat (limited to 'src/3rdparty/phonon/mmf/videoplayer_dsa.cpp')
-rw-r--r-- | src/3rdparty/phonon/mmf/videoplayer_dsa.cpp | 285 |
1 files changed, 285 insertions, 0 deletions
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 <http://www.gnu.org/licenses/>. + +*/ + +#include <coecntrl.h> // for CCoeControl + +#include <QApplication> // for QApplication::activeWindow +#include <QtCore/private/qcore_symbian_p.h> // for qt_TRect2QRect + +#include "utils.h" +#include "videooutput_dsa.h" +#include "videoplayer_dsa.h" + +QT_BEGIN_NAMESPACE + +using namespace Phonon; +using namespace Phonon::MMF; + +// Two-phase constructor idiom is used because construct() calls virtual +// functions and therefore cannot be called from the AbstractVideoPlayer +// C++ constructor. +DsaVideoPlayer* DsaVideoPlayer::create(MediaObject *parent, + const AbstractPlayer *player) +{ + QScopedPointer<DsaVideoPlayer> self(new DsaVideoPlayer(parent, player)); + self->construct(); + return self.take(); +} + +DsaVideoPlayer::DsaVideoPlayer(MediaObject *parent, const AbstractPlayer *player) + : AbstractVideoPlayer(parent, player) + , m_dsaActive(false) + , m_dsaWasActive(false) +{ + +} + +DsaVideoPlayer::~DsaVideoPlayer() +{ + +} + + +//----------------------------------------------------------------------------- +// Public functions +//----------------------------------------------------------------------------- + +void MMF::DsaVideoPlayer::videoWindowScreenRectChanged() +{ + QRect windowRect = static_cast<DsaVideoOutput *>(m_videoOutput)->videoWindowScreenRect(); + + // Clip to physical window size + // This is due to a defect in the layout when running on S60 3.2, which + // results in the rectangle of the video widget extending outside the + // screen in certain circumstances. These include the initial startup + // of the mediaplayer demo in portrait mode. When this rectangle is + // passed to the CVideoPlayerUtility, no video is rendered. + const TSize screenSize = m_screenDevice.SizeInPixels(); + const QRect screenRect(0, 0, screenSize.iWidth, screenSize.iHeight); + windowRect = windowRect.intersected(screenRect); + + // Recalculate scale factors. Pass 'false' as second parameter in order to + // suppress application of the change to the player - this is done at the end + // of the function. + updateScaleFactors(windowRect.size(), false); + + m_videoScreenRect = qt_QRect2TRect(windowRect); + + parametersChanged(WindowScreenRect | ScaleFactors); +} + +void MMF::DsaVideoPlayer::suspendDirectScreenAccess() +{ + m_dsaWasActive = stopDirectScreenAccess(); +} + +void MMF::DsaVideoPlayer::resumeDirectScreenAccess() +{ + if (m_dsaWasActive) { + startDirectScreenAccess(); + m_dsaWasActive = false; + } +} + + +//----------------------------------------------------------------------------- +// Private functions +//----------------------------------------------------------------------------- + +void MMF::DsaVideoPlayer::createPlayer() +{ + // A window handle must be provided in order to construct + // CVideoPlayerUtility. If no VideoOutput has yet been connected to this + // player, we temporarily use the top-level application window handle. + // No video ever gets rendered into this window; SetDisplayWindowL is + // always called before rendering actually begins. + if (!m_window) + m_window = QApplication::activeWindow()->effectiveWinId()->DrawableWindow(); + + const TInt priority = 0; + const TMdaPriorityPreference preference = EMdaPriorityPreferenceNone; + + CVideoPlayerUtility *player = 0; + QT_TRAP_THROWING(player = CVideoPlayerUtility::NewL(*this, + priority, preference, + m_wsSession, m_screenDevice, + *m_window, + m_videoScreenRect, m_videoScreenRect)); + m_player.reset(player); + + // CVideoPlayerUtility::NewL starts DSA + m_dsaActive = true; + + 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; i<region->Count(); ++i) { + const TRect& rect = region->RectangleList()[i]; + qDebug() << "Phonon::MMF::getDsaRegion rect" + << rect.iTl.iX << rect.iTl.iY << rect.iBr.iX << rect.iBr.iY; + } + region->Close(); + } +} + +#endif // QT_NO_DEBUG + +void MMF::DsaVideoPlayer::handleParametersChanged(VideoParameters parameters) +{ + TRACE_CONTEXT(DsaVideoPlayer::handleParametersChanged, EVideoInternal); + TRACE_ENTRY_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 + |