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

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

trunk: Merged in qt 4.7.2 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 Q_ASSERT(m_videoOutput);
65
66 QRect windowRect = static_cast<DsaVideoOutput *>(m_videoOutput)->videoWindowScreenRect();
67
68 // Clip to physical window size
69 // This is due to a defect in the layout when running on S60 3.2, which
70 // results in the rectangle of the video widget extending outside the
71 // screen in certain circumstances. These include the initial startup
72 // of the mediaplayer demo in portrait mode. When this rectangle is
73 // passed to the CVideoPlayerUtility, no video is rendered.
74 const TSize screenSize = m_screenDevice.SizeInPixels();
75 const QRect screenRect(0, 0, screenSize.iWidth, screenSize.iHeight);
76 windowRect = windowRect.intersected(screenRect);
77
78 // Recalculate scale factors. Pass 'false' as second parameter in order to
79 // suppress application of the change to the player - this is done at the end
80 // of the function.
81 updateScaleFactors(windowRect.size(), false);
82
83 m_videoScreenRect = qt_QRect2TRect(windowRect);
84
85 parametersChanged(WindowScreenRect | ScaleFactors);
86}
87
88void MMF::DsaVideoPlayer::suspendDirectScreenAccess()
89{
90 m_dsaWasActive = stopDirectScreenAccess();
91}
92
93void MMF::DsaVideoPlayer::resumeDirectScreenAccess()
94{
95 if (m_dsaWasActive) {
96 startDirectScreenAccess();
97 m_dsaWasActive = false;
98 }
99}
100
101
102//-----------------------------------------------------------------------------
103// Private functions
104//-----------------------------------------------------------------------------
105
106void MMF::DsaVideoPlayer::createPlayer()
107{
108 // A window handle must be provided in order to construct
109 // CVideoPlayerUtility. If no VideoOutput has yet been connected to this
110 // player, we temporarily use the top-level application window handle.
111 // No video ever gets rendered into this window; SetDisplayWindowL is
112 // always called before rendering actually begins.
113 if (!m_window)
114 m_window = QApplication::activeWindow()->effectiveWinId()->DrawableWindow();
115
116 const TInt priority = 0;
117 const TMdaPriorityPreference preference = EMdaPriorityPreferenceNone;
118
119 CVideoPlayerUtility *player = 0;
120 QT_TRAP_THROWING(player = CVideoPlayerUtility::NewL(*this,
121 priority, preference,
122 m_wsSession, m_screenDevice,
123 *m_window,
124 m_videoScreenRect, m_videoScreenRect));
125 m_player.reset(player);
126
127 // CVideoPlayerUtility::NewL starts DSA
128 m_dsaActive = true;
129}
130
131void MMF::DsaVideoPlayer::initVideoOutput()
132{
133 Q_ASSERT(m_videoOutput);
134
135 bool connected = connect(
136 m_videoOutput, SIGNAL(videoWindowScreenRectChanged()),
137 this, SLOT(videoWindowScreenRectChanged())
138 );
139 Q_ASSERT(connected);
140
141 connected = connect(
142 m_videoOutput, SIGNAL(beginVideoWindowNativePaint()),
143 this, SLOT(suspendDirectScreenAccess())
144 );
145 Q_ASSERT(connected);
146
147 connected = connect(
148 m_videoOutput, SIGNAL(endVideoWindowNativePaint()),
149 this, SLOT(resumeDirectScreenAccess())
150 );
151 Q_ASSERT(connected);
152
153 // Suppress warnings in release builds
154 Q_UNUSED(connected);
155
156 AbstractVideoPlayer::initVideoOutput();
157}
158
159void MMF::DsaVideoPlayer::prepareCompleted()
160{
161 if (m_videoOutput)
162 videoWindowScreenRectChanged();
163}
164
165void MMF::DsaVideoPlayer::handleVideoWindowChanged()
166{
167 if (!m_window) {
168 if (QWidget *window = QApplication::activeWindow())
169 m_window = window->effectiveWinId()->DrawableWindow();
170 else
171 m_window = 0;
172 m_videoScreenRect = TRect();
173 }
174
175 parametersChanged(WindowHandle | WindowScreenRect);
176}
177
178#ifndef QT_NO_DEBUG
179
180// The following code is for debugging problems related to video visibility. It allows
181// the VideoPlayer instance to query the window server in order to determine the
182// DSA drawing region for the video window.
183
184class CDummyAO : public CActive
185{
186public:
187 CDummyAO() : CActive(CActive::EPriorityStandard) { CActiveScheduler::Add(this); }
188 void RunL() { }
189 void DoCancel() { }
190 TRequestStatus& Status() { return iStatus; }
191 void SetActive() { CActive::SetActive(); }
192};
193
194void getDsaRegion(RWsSession &session, const RWindowBase &window)
195{
196 // Dump complete window tree
197 session.LogCommand(RWsSession::ELoggingStatusDump);
198
199 RDirectScreenAccess dsa(session);
200 TInt err = dsa.Construct();
201 CDummyAO ao;
202 RRegion* region;
203 err = dsa.Request(region, ao.Status(), window);
204 ao.SetActive();
205 dsa.Close();
206 ao.Cancel();
207 if (region) {
208 qDebug() << "Phonon::MMF::getDsaRegion count" << region->Count();
209 for (int i=0; i<region->Count(); ++i) {
210 const TRect& rect = region->RectangleList()[i];
211 qDebug() << "Phonon::MMF::getDsaRegion rect"
212 << rect.iTl.iX << rect.iTl.iY << rect.iBr.iX << rect.iBr.iY;
213 }
214 region->Close();
215 }
216}
217
218#endif // QT_NO_DEBUG
219
220void MMF::DsaVideoPlayer::handleParametersChanged(VideoParameters parameters)
221{
222 TRACE_CONTEXT(DsaVideoPlayer::handleParametersChanged, EVideoInternal);
223 TRACE_ENTRY("parameters 0x%x", parameters.operator int());
224
225 if (!m_window)
226 return;
227
228#ifndef QT_NO_DEBUG
229 getDsaRegion(m_wsSession, *m_window);
230#endif
231
232 if (m_player) {
233 static const TBool antialias = ETrue;
234 int err = KErrNone;
235
236 if (parameters & ScaleFactors) {
237 TRAP(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight,
238 antialias));
239 if(KErrNone != err) {
240 TRACE("SetScaleFactorL (1) err %d", err);
241 setError(tr("Video display error"), err);
242 }
243 }
244
245 if (KErrNone == err) {
246 if (parameters & WindowHandle || parameters & WindowScreenRect) {
247 TRAP(err,
248 m_player->SetDisplayWindowL(m_wsSession, m_screenDevice,
249 *m_window,
250 m_videoScreenRect,
251 m_videoScreenRect));
252 }
253
254 if (KErrNone != err) {
255 TRACE("SetDisplayWindowL err %d", err);
256 setError(tr("Video display error"), err);
257 } else {
258 m_dsaActive = true;
259 if (parameters & ScaleFactors) {
260 TRAP(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight,
261 antialias));
262 if (KErrNone != err) {
263 TRACE("SetScaleFactorL (2) err %d", err);
264 setError(tr("Video display error"), err);
265 }
266 }
267 }
268 }
269 }
270
271 TRACE_EXIT_0();
272}
273
274void MMF::DsaVideoPlayer::startDirectScreenAccess()
275{
276 TRACE_CONTEXT(DsaVideoPlayer::startDirectScreenAccess, EVideoInternal);
277 TRACE_ENTRY("dsaActive %d", m_dsaActive);
278
279 int err = KErrNone;
280
281 if (!m_dsaActive) {
282 TRAP(err, m_player->StartDirectScreenAccessL());
283 if (KErrNone == err)
284 m_dsaActive = true;
285 else
286 setError(tr("Video display error"), err);
287 }
288
289 if (m_videoOutput)
290 m_videoOutput->dump();
291
292 TRACE_EXIT("error %d", err);
293}
294
295bool MMF::DsaVideoPlayer::stopDirectScreenAccess()
296{
297 TRACE_CONTEXT(DsaVideoPlayer::stopDirectScreenAccess, EVideoInternal);
298 TRACE_ENTRY("dsaActive %d", m_dsaActive);
299
300 int err = KErrNone;
301
302 const bool dsaWasActive = m_dsaActive;
303 if (m_dsaActive) {
304 TRAP(err, m_player->StopDirectScreenAccessL());
305 if (KErrNone == err)
306 m_dsaActive = false;
307 else
308 setError(tr("Video display error"), err);
309 }
310
311 TRACE_EXIT("error %d", err);
312
313 return dsaWasActive;
314}
315
316QT_END_NAMESPACE
317
Note: See TracBrowser for help on using the repository browser.