src/3rdparty/phonon/mmf/videoplayer_dsa.cpp
changeset 19 fcece45ef507
child 14 c0432d11811c
equal deleted inserted replaced
18:2f34d5167611 19:fcece45ef507
       
     1 /*  This file is part of the KDE project.
       
     2 
       
     3 Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 
       
     5 This library is free software: you can redistribute it and/or modify
       
     6 it under the terms of the GNU Lesser General Public License as published by
       
     7 the Free Software Foundation, either version 2.1 or 3 of the License.
       
     8 
       
     9 This library is distributed in the hope that it will be useful,
       
    10 but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    12 GNU Lesser General Public License for more details.
       
    13 
       
    14 You should have received a copy of the GNU Lesser General Public License
       
    15 along with this library.  If not, see <http://www.gnu.org/licenses/>.
       
    16 
       
    17 */
       
    18 
       
    19 #include <coecntrl.h> // for CCoeControl
       
    20 
       
    21 #include <QApplication>    // for QApplication::activeWindow
       
    22 #include <QtCore/private/qcore_symbian_p.h> // for qt_TRect2QRect
       
    23 
       
    24 #include "utils.h"
       
    25 #include "videooutput_dsa.h"
       
    26 #include "videoplayer_dsa.h"
       
    27 
       
    28 QT_BEGIN_NAMESPACE
       
    29 
       
    30 using namespace Phonon;
       
    31 using namespace Phonon::MMF;
       
    32 
       
    33 // Two-phase constructor idiom is used because construct() calls virtual
       
    34 // functions and therefore cannot be called from the AbstractVideoPlayer
       
    35 // C++ constructor.
       
    36 DsaVideoPlayer* DsaVideoPlayer::create(MediaObject *parent,
       
    37                                        const AbstractPlayer *player)
       
    38 {
       
    39     QScopedPointer<DsaVideoPlayer> self(new DsaVideoPlayer(parent, player));
       
    40     self->construct();
       
    41     return self.take();
       
    42 }
       
    43 
       
    44 DsaVideoPlayer::DsaVideoPlayer(MediaObject *parent, const AbstractPlayer *player)
       
    45     :   AbstractVideoPlayer(parent, player)
       
    46     ,   m_dsaActive(false)
       
    47     ,   m_dsaWasActive(false)
       
    48 {
       
    49 
       
    50 }
       
    51 
       
    52 DsaVideoPlayer::~DsaVideoPlayer()
       
    53 {
       
    54 
       
    55 }
       
    56 
       
    57 
       
    58 //-----------------------------------------------------------------------------
       
    59 // Public functions
       
    60 //-----------------------------------------------------------------------------
       
    61 
       
    62 void MMF::DsaVideoPlayer::videoWindowScreenRectChanged()
       
    63 {
       
    64     QRect windowRect = static_cast<DsaVideoOutput *>(m_videoOutput)->videoWindowScreenRect();
       
    65 
       
    66     // Clip to physical window size
       
    67     // This is due to a defect in the layout when running on S60 3.2, which
       
    68     // results in the rectangle of the video widget extending outside the
       
    69     // screen in certain circumstances.  These include the initial startup
       
    70     // of the mediaplayer demo in portrait mode.  When this rectangle is
       
    71     // passed to the CVideoPlayerUtility, no video is rendered.
       
    72     const TSize screenSize = m_screenDevice.SizeInPixels();
       
    73     const QRect screenRect(0, 0, screenSize.iWidth, screenSize.iHeight);
       
    74     windowRect = windowRect.intersected(screenRect);
       
    75 
       
    76     // Recalculate scale factors.  Pass 'false' as second parameter in order to
       
    77     // suppress application of the change to the player - this is done at the end
       
    78     // of the function.
       
    79     updateScaleFactors(windowRect.size(), false);
       
    80 
       
    81     m_videoScreenRect = qt_QRect2TRect(windowRect);
       
    82 
       
    83     parametersChanged(WindowScreenRect | ScaleFactors);
       
    84 }
       
    85 
       
    86 void MMF::DsaVideoPlayer::suspendDirectScreenAccess()
       
    87 {
       
    88     m_dsaWasActive = stopDirectScreenAccess();
       
    89 }
       
    90 
       
    91 void MMF::DsaVideoPlayer::resumeDirectScreenAccess()
       
    92 {
       
    93     if (m_dsaWasActive) {
       
    94         startDirectScreenAccess();
       
    95         m_dsaWasActive = false;
       
    96     }
       
    97 }
       
    98 
       
    99 
       
   100 //-----------------------------------------------------------------------------
       
   101 // Private functions
       
   102 //-----------------------------------------------------------------------------
       
   103 
       
   104 void MMF::DsaVideoPlayer::createPlayer()
       
   105 {
       
   106     // A window handle must be provided in order to construct
       
   107     // CVideoPlayerUtility.  If no VideoOutput has yet been connected to this
       
   108     // player, we temporarily use the top-level application window handle.
       
   109     // No video ever gets rendered into this window; SetDisplayWindowL is
       
   110     // always called before rendering actually begins.
       
   111     if (!m_window)
       
   112         m_window = QApplication::activeWindow()->effectiveWinId()->DrawableWindow();
       
   113 
       
   114     const TInt priority = 0;
       
   115     const TMdaPriorityPreference preference = EMdaPriorityPreferenceNone;
       
   116 
       
   117     CVideoPlayerUtility *player = 0;
       
   118     QT_TRAP_THROWING(player = CVideoPlayerUtility::NewL(*this,
       
   119                                      priority, preference,
       
   120                                      m_wsSession, m_screenDevice,
       
   121                                      *m_window,
       
   122                                      m_videoScreenRect, m_videoScreenRect));
       
   123     m_player.reset(player);
       
   124 
       
   125     // CVideoPlayerUtility::NewL starts DSA
       
   126     m_dsaActive = true;
       
   127 
       
   128     m_player->RegisterForVideoLoadingNotification(*this);
       
   129 }
       
   130 
       
   131 void MMF::DsaVideoPlayer::initVideoOutput()
       
   132 {
       
   133     bool connected = connect(
       
   134         m_videoOutput, SIGNAL(videoWindowScreenRectChanged()),
       
   135         this, SLOT(videoWindowScreenRectChanged())
       
   136     );
       
   137     Q_ASSERT(connected);
       
   138 
       
   139     connected = connect(
       
   140         m_videoOutput, SIGNAL(beginVideoWindowNativePaint()),
       
   141         this, SLOT(suspendDirectScreenAccess())
       
   142     );
       
   143     Q_ASSERT(connected);
       
   144 
       
   145     connected = connect(
       
   146         m_videoOutput, SIGNAL(endVideoWindowNativePaint()),
       
   147         this, SLOT(resumeDirectScreenAccess())
       
   148     );
       
   149     Q_ASSERT(connected);
       
   150 
       
   151     // Suppress warnings in release builds
       
   152     Q_UNUSED(connected);
       
   153 
       
   154     AbstractVideoPlayer::initVideoOutput();
       
   155 }
       
   156 
       
   157 void MMF::DsaVideoPlayer::prepareCompleted()
       
   158 {
       
   159     videoWindowScreenRectChanged();
       
   160 }
       
   161 
       
   162 void MMF::DsaVideoPlayer::handleVideoWindowChanged()
       
   163 {
       
   164     if (!m_window) {
       
   165         if (QWidget *window = QApplication::activeWindow())
       
   166             m_window = window->effectiveWinId()->DrawableWindow();
       
   167         else
       
   168             m_window = 0;
       
   169         m_videoScreenRect = TRect();
       
   170     }
       
   171 
       
   172     parametersChanged(WindowHandle | WindowScreenRect);
       
   173 }
       
   174 
       
   175 #ifndef QT_NO_DEBUG
       
   176 
       
   177 // The following code is for debugging problems related to video visibility.  It allows
       
   178 // the VideoPlayer instance to query the window server in order to determine the
       
   179 // DSA drawing region for the video window.
       
   180 
       
   181 class CDummyAO : public CActive
       
   182 {
       
   183 public:
       
   184     CDummyAO() : CActive(CActive::EPriorityStandard) { CActiveScheduler::Add(this); }
       
   185     void RunL() { }
       
   186     void DoCancel() { }
       
   187     TRequestStatus& Status() { return iStatus; }
       
   188     void SetActive() { CActive::SetActive(); }
       
   189 };
       
   190 
       
   191 void getDsaRegion(RWsSession &session, const RWindowBase &window)
       
   192 {
       
   193     RDirectScreenAccess dsa(session);
       
   194     TInt err = dsa.Construct();
       
   195     CDummyAO ao;
       
   196     RRegion* region;
       
   197     err = dsa.Request(region, ao.Status(), window);
       
   198     ao.SetActive();
       
   199     dsa.Close();
       
   200     ao.Cancel();
       
   201     if (region) {
       
   202         qDebug() << "Phonon::MMF::getDsaRegion count" << region->Count();
       
   203         for (int i=0; i<region->Count(); ++i) {
       
   204             const TRect& rect = region->RectangleList()[i];
       
   205             qDebug() << "Phonon::MMF::getDsaRegion rect"
       
   206                 << rect.iTl.iX << rect.iTl.iY << rect.iBr.iX << rect.iBr.iY;
       
   207         }
       
   208         region->Close();
       
   209     }
       
   210 }
       
   211 
       
   212 #endif // QT_NO_DEBUG
       
   213 
       
   214 void MMF::DsaVideoPlayer::handleParametersChanged(VideoParameters parameters)
       
   215 {
       
   216     TRACE_CONTEXT(DsaVideoPlayer::handleParametersChanged, EVideoInternal);
       
   217     TRACE_ENTRY_0();
       
   218 
       
   219     if (!m_window)
       
   220         return;
       
   221 
       
   222 #ifndef QT_NO_DEBUG
       
   223     getDsaRegion(m_wsSession, *m_window);
       
   224 #endif
       
   225 
       
   226     static const TBool antialias = ETrue;
       
   227     int err = KErrNone;
       
   228 
       
   229     if (parameters & ScaleFactors) {
       
   230         TRAP(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight,
       
   231                                             antialias));
       
   232         if(KErrNone != err) {
       
   233             TRACE("SetScaleFactorL (1) err %d", err);
       
   234             setError(tr("Video display error"), err);
       
   235         }
       
   236     }
       
   237 
       
   238     if (KErrNone == err) {
       
   239         if (parameters & WindowHandle || parameters & WindowScreenRect) {
       
   240             TRAP(err,
       
   241                 m_player->SetDisplayWindowL(m_wsSession, m_screenDevice,
       
   242                                             *m_window,
       
   243                                             m_videoScreenRect,
       
   244                                             m_videoScreenRect));
       
   245         }
       
   246 
       
   247         if (KErrNone != err) {
       
   248             TRACE("SetDisplayWindowL err %d", err);
       
   249             setError(tr("Video display error"), err);
       
   250         } else {
       
   251             m_dsaActive = true;
       
   252             if (parameters & ScaleFactors) {
       
   253                 TRAP(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight,
       
   254                                                     antialias));
       
   255                 if (KErrNone != err) {
       
   256                     TRACE("SetScaleFactorL (2) err %d", err);
       
   257                     setError(tr("Video display error"), err);
       
   258                 }
       
   259             }
       
   260         }
       
   261     }
       
   262 
       
   263     TRACE_EXIT_0();
       
   264 }
       
   265 
       
   266 void MMF::DsaVideoPlayer::startDirectScreenAccess()
       
   267 {
       
   268     if (!m_dsaActive) {
       
   269         TRAPD(err, m_player->StartDirectScreenAccessL());
       
   270         if (KErrNone == err)
       
   271             m_dsaActive = true;
       
   272         else
       
   273             setError(tr("Video display error"), err);
       
   274     }
       
   275 }
       
   276 
       
   277 bool MMF::DsaVideoPlayer::stopDirectScreenAccess()
       
   278 {
       
   279     const bool dsaWasActive = m_dsaActive;
       
   280     if (m_dsaActive) {
       
   281         TRAPD(err, m_player->StopDirectScreenAccessL());
       
   282         if (KErrNone == err)
       
   283             m_dsaActive = false;
       
   284         else
       
   285             setError(tr("Video display error"), err);
       
   286     }
       
   287     return dsaWasActive;
       
   288 }
       
   289 
       
   290 QT_END_NAMESPACE
       
   291