source: trunk/src/3rdparty/phonon/mmf/videoplayer_dsa.cpp@ 769

Last change on this file since 769 was 769, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.3 sources from branches/vendor/nokia/qt.

File size: 9.6 KB
Line 
1/* This file is part of the KDE project.
2
3Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4
5This library is free software: you can redistribute it and/or modify
6it under the terms of the GNU Lesser General Public License as published by
7the Free Software Foundation, either version 2.1 or 3 of the License.
8
9This library is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU Lesser General Public License for more details.
13
14You should have received a copy of the GNU Lesser General Public License
15along 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
28QT_BEGIN_NAMESPACE
29
30using namespace Phonon;
31using 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.
36DsaVideoPlayer* 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
44DsaVideoPlayer::DsaVideoPlayer(MediaObject *parent, const AbstractPlayer *player)
45 : AbstractVideoPlayer(parent, player)
46 , m_dsaActive(false)
47 , m_dsaWasActive(false)
48{
49
50}
51
52DsaVideoPlayer::~DsaVideoPlayer()
53{
54
55}
56
57
58//-----------------------------------------------------------------------------
59// Public functions
60//-----------------------------------------------------------------------------
61
62void 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
86void MMF::DsaVideoPlayer::suspendDirectScreenAccess()
87{
88 m_dsaWasActive = stopDirectScreenAccess();
89}
90
91void MMF::DsaVideoPlayer::resumeDirectScreenAccess()
92{
93 if (m_dsaWasActive) {
94 startDirectScreenAccess();
95 m_dsaWasActive = false;
96 }
97}
98
99
100//-----------------------------------------------------------------------------
101// Private functions
102//-----------------------------------------------------------------------------
103
104void 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
131void 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
157void MMF::DsaVideoPlayer::prepareCompleted()
158{
159 videoWindowScreenRectChanged();
160}
161
162void 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
181class CDummyAO : public CActive
182{
183public:
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
191void getDsaRegion(RWsSession &session, const RWindowBase &window)
192{
193 // Dump complete window tree
194 session.LogCommand(RWsSession::ELoggingStatusDump);
195
196 RDirectScreenAccess dsa(session);
197 TInt err = dsa.Construct();
198 CDummyAO ao;
199 RRegion* region;
200 err = dsa.Request(region, ao.Status(), window);
201 ao.SetActive();
202 dsa.Close();
203 ao.Cancel();
204 if (region) {
205 qDebug() << "Phonon::MMF::getDsaRegion count" << region->Count();
206 for (int i=0; i<region->Count(); ++i) {
207 const TRect& rect = region->RectangleList()[i];
208 qDebug() << "Phonon::MMF::getDsaRegion rect"
209 << rect.iTl.iX << rect.iTl.iY << rect.iBr.iX << rect.iBr.iY;
210 }
211 region->Close();
212 }
213}
214
215#endif // QT_NO_DEBUG
216
217void MMF::DsaVideoPlayer::handleParametersChanged(VideoParameters parameters)
218{
219 TRACE_CONTEXT(DsaVideoPlayer::handleParametersChanged, EVideoInternal);
220 TRACE_ENTRY("parameters 0x%x", parameters.operator int());
221
222 if (!m_window)
223 return;
224
225#ifndef QT_NO_DEBUG
226 getDsaRegion(m_wsSession, *m_window);
227#endif
228
229 if (m_player) {
230 static const TBool antialias = ETrue;
231 int err = KErrNone;
232
233 if (parameters & ScaleFactors) {
234 TRAP(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight,
235 antialias));
236 if(KErrNone != err) {
237 TRACE("SetScaleFactorL (1) err %d", err);
238 setError(tr("Video display error"), err);
239 }
240 }
241
242 if (KErrNone == err) {
243 if (parameters & WindowHandle || parameters & WindowScreenRect) {
244 TRAP(err,
245 m_player->SetDisplayWindowL(m_wsSession, m_screenDevice,
246 *m_window,
247 m_videoScreenRect,
248 m_videoScreenRect));
249 }
250
251 if (KErrNone != err) {
252 TRACE("SetDisplayWindowL err %d", err);
253 setError(tr("Video display error"), err);
254 } else {
255 m_dsaActive = true;
256 if (parameters & ScaleFactors) {
257 TRAP(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight,
258 antialias));
259 if (KErrNone != err) {
260 TRACE("SetScaleFactorL (2) err %d", err);
261 setError(tr("Video display error"), err);
262 }
263 }
264 }
265 }
266 }
267
268 TRACE_EXIT_0();
269}
270
271void MMF::DsaVideoPlayer::startDirectScreenAccess()
272{
273 TRACE_CONTEXT(DsaVideoPlayer::startDirectScreenAccess, EVideoInternal);
274 TRACE_ENTRY("dsaActive %d", m_dsaActive);
275
276 int err = KErrNone;
277
278 if (!m_dsaActive) {
279 TRAP(err, m_player->StartDirectScreenAccessL());
280 if (KErrNone == err)
281 m_dsaActive = true;
282 else
283 setError(tr("Video display error"), err);
284 }
285
286 if (m_videoOutput)
287 m_videoOutput->dump();
288
289 TRACE_EXIT("error %d", err);
290}
291
292bool MMF::DsaVideoPlayer::stopDirectScreenAccess()
293{
294 TRACE_CONTEXT(DsaVideoPlayer::stopDirectScreenAccess, EVideoInternal);
295 TRACE_ENTRY("dsaActive %d", m_dsaActive);
296
297 int err = KErrNone;
298
299 const bool dsaWasActive = m_dsaActive;
300 if (m_dsaActive) {
301 TRAP(err, m_player->StopDirectScreenAccessL());
302 if (KErrNone == err)
303 m_dsaActive = false;
304 else
305 setError(tr("Video display error"), err);
306 }
307
308 TRACE_EXIT("error %d", err);
309
310 return dsaWasActive;
311}
312
313QT_END_NAMESPACE
314
Note: See TracBrowser for help on using the repository browser.