1 /*
2 Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
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 GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18 */
19
20 #include "config.h"
21 #include "MediaPlayerPrivateQt.h"
22
23 #include "FrameView.h"
24 #include "GraphicsContext.h"
25 #include "HTMLMediaElement.h"
26 #include "HTMLVideoElement.h"
27 #include "NetworkingContext.h"
28 #include "NotImplemented.h"
29 #include "RenderVideo.h"
30 #include "TimeRanges.h"
31 #include "Widget.h"
32 #include "qwebframe.h"
33 #include "qwebpage.h"
34
35 #include <QGraphicsScene>
36 #include <QGraphicsVideoItem>
37 #include <QMediaPlayerControl>
38 #include <QMediaService>
39 #include <QNetworkAccessManager>
40 #include <QNetworkCookieJar>
41 #include <QNetworkRequest>
42 #include <QPainter>
43 #include <QPoint>
44 #include <QRect>
45 #include <QStyleOptionGraphicsItem>
46 #include <QTime>
47 #include <QTimer>
48 #include <QUrl>
49 #include <limits>
50 #include <wtf/HashSet.h>
51 #include <wtf/text/CString.h>
52
53 #if USE(ACCELERATED_COMPOSITING)
54 #include "texmap/TextureMapperPlatformLayer.h"
55 #endif
56
57 using namespace WTF;
58
59 namespace WebCore {
60
create(MediaPlayer * player)61 MediaPlayerPrivateInterface* MediaPlayerPrivateQt::create(MediaPlayer* player)
62 {
63 return new MediaPlayerPrivateQt(player);
64 }
65
registerMediaEngine(MediaEngineRegistrar registrar)66 void MediaPlayerPrivateQt::registerMediaEngine(MediaEngineRegistrar registrar)
67 {
68 registrar(create, getSupportedTypes, supportsType, 0, 0, 0);
69 }
70
getSupportedTypes(HashSet<String> & supported)71 void MediaPlayerPrivateQt::getSupportedTypes(HashSet<String> &supported)
72 {
73 QStringList types = QMediaPlayer::supportedMimeTypes();
74
75 for (int i = 0; i < types.size(); i++) {
76 QString mime = types.at(i);
77 if (mime.startsWith(QString::fromLatin1("audio/")) || mime.startsWith(QString::fromLatin1("video/")))
78 supported.add(mime);
79 }
80 }
81
supportsType(const String & mime,const String & codec)82 MediaPlayer::SupportsType MediaPlayerPrivateQt::supportsType(const String& mime, const String& codec)
83 {
84 if (!mime.startsWith("audio/") && !mime.startsWith("video/"))
85 return MediaPlayer::IsNotSupported;
86
87 // Parse and trim codecs.
88 QString codecStr = codec;
89 QStringList codecList = codecStr.split(QLatin1Char(','), QString::SkipEmptyParts);
90 QStringList codecListTrimmed;
91 foreach (const QString& codecStrNotTrimmed, codecList) {
92 QString codecStrTrimmed = codecStrNotTrimmed.trimmed();
93 if (!codecStrTrimmed.isEmpty())
94 codecListTrimmed.append(codecStrTrimmed);
95 }
96
97 if (QMediaPlayer::hasSupport(mime, codecListTrimmed) >= QtMultimediaKit::ProbablySupported)
98 return MediaPlayer::IsSupported;
99
100 return MediaPlayer::MayBeSupported;
101 }
102
MediaPlayerPrivateQt(MediaPlayer * player)103 MediaPlayerPrivateQt::MediaPlayerPrivateQt(MediaPlayer* player)
104 : m_webCorePlayer(player)
105 , m_mediaPlayer(new QMediaPlayer)
106 , m_mediaPlayerControl(0)
107 , m_videoItem(new QGraphicsVideoItem)
108 , m_videoScene(new QGraphicsScene)
109 , m_networkState(MediaPlayer::Empty)
110 , m_readyState(MediaPlayer::HaveNothing)
111 , m_currentSize(0, 0)
112 , m_naturalSize(RenderVideo::defaultSize())
113 , m_isVisible(false)
114 , m_isSeeking(false)
115 , m_composited(false)
116 , m_preload(MediaPlayer::Auto)
117 , m_suppressNextPlaybackChanged(false)
118 {
119 m_mediaPlayer->setVideoOutput(m_videoItem);
120 m_videoScene->addItem(m_videoItem);
121
122 // Signal Handlers
123 connect(m_mediaPlayer, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),
124 this, SLOT(mediaStatusChanged(QMediaPlayer::MediaStatus)));
125 connect(m_mediaPlayer, SIGNAL(stateChanged(QMediaPlayer::State)),
126 this, SLOT(stateChanged(QMediaPlayer::State)));
127 connect(m_mediaPlayer, SIGNAL(error(QMediaPlayer::Error)),
128 this, SLOT(handleError(QMediaPlayer::Error)));
129 connect(m_mediaPlayer, SIGNAL(bufferStatusChanged(int)),
130 this, SLOT(bufferStatusChanged(int)));
131 connect(m_mediaPlayer, SIGNAL(durationChanged(qint64)),
132 this, SLOT(durationChanged(qint64)));
133 connect(m_mediaPlayer, SIGNAL(positionChanged(qint64)),
134 this, SLOT(positionChanged(qint64)));
135 connect(m_mediaPlayer, SIGNAL(volumeChanged(int)),
136 this, SLOT(volumeChanged(int)));
137 connect(m_mediaPlayer, SIGNAL(mutedChanged(bool)),
138 this, SLOT(mutedChanged(bool)));
139 connect(m_videoScene, SIGNAL(changed(QList<QRectF>)),
140 this, SLOT(repaint()));
141 connect(m_videoItem, SIGNAL(nativeSizeChanged(QSizeF)),
142 this, SLOT(nativeSizeChanged(QSizeF)));
143
144 // Grab the player control
145 if (QMediaService* service = m_mediaPlayer->service()) {
146 m_mediaPlayerControl = qobject_cast<QMediaPlayerControl *>(
147 service->requestControl(QMediaPlayerControl_iid));
148 }
149 }
150
~MediaPlayerPrivateQt()151 MediaPlayerPrivateQt::~MediaPlayerPrivateQt()
152 {
153 m_mediaPlayer->disconnect(this);
154 m_mediaPlayer->stop();
155 m_mediaPlayer->setMedia(QMediaContent());
156
157 delete m_mediaPlayer;
158 delete m_videoScene;
159 }
160
hasVideo() const161 bool MediaPlayerPrivateQt::hasVideo() const
162 {
163 return m_mediaPlayer->isVideoAvailable();
164 }
165
hasAudio() const166 bool MediaPlayerPrivateQt::hasAudio() const
167 {
168 return true;
169 }
170
load(const String & url)171 void MediaPlayerPrivateQt::load(const String& url)
172 {
173 m_mediaUrl = url;
174
175 // QtMultimedia does not have an API to throttle loading
176 // so we handle this ourselves by delaying the load
177 if (m_preload == MediaPlayer::None) {
178 m_delayingLoad = true;
179 return;
180 }
181
182 commitLoad(url);
183 }
184
commitLoad(const String & url)185 void MediaPlayerPrivateQt::commitLoad(const String& url)
186 {
187 // We are now loading
188 if (m_networkState != MediaPlayer::Loading) {
189 m_networkState = MediaPlayer::Loading;
190 m_webCorePlayer->networkStateChanged();
191 }
192
193 // And we don't have any data yet
194 if (m_readyState != MediaPlayer::HaveNothing) {
195 m_readyState = MediaPlayer::HaveNothing;
196 m_webCorePlayer->readyStateChanged();
197 }
198
199 KURL kUrl(ParsedURLString, url);
200 const QUrl rUrl = kUrl;
201 const QString scheme = rUrl.scheme().toLower();
202
203 // Grab the client media element
204 HTMLMediaElement* element = static_cast<HTMLMediaElement*>(m_webCorePlayer->mediaPlayerClient());
205
206 // Construct the media content with a network request if the resource is http[s]
207 if (scheme == QString::fromLatin1("http") || scheme == QString::fromLatin1("https")) {
208 QNetworkRequest request = QNetworkRequest(rUrl);
209
210 // Grab the current document
211 Document* document = element->document();
212 if (!document)
213 document = element->ownerDocument();
214
215 // Grab the frame and network manager
216 Frame* frame = document ? document->frame() : 0;
217 FrameLoader* frameLoader = frame ? frame->loader() : 0;
218 QNetworkAccessManager* manager = frameLoader ? frameLoader->networkingContext()->networkAccessManager() : 0;
219
220 if (manager) {
221 // Set the cookies
222 QNetworkCookieJar* jar = manager->cookieJar();
223 QList<QNetworkCookie> cookies = jar->cookiesForUrl(rUrl);
224
225 // Don't set the header if there are no cookies.
226 // This prevents a warning from being emitted.
227 if (!cookies.isEmpty())
228 request.setHeader(QNetworkRequest::CookieHeader, QVariant::fromValue(cookies));
229
230 // Set the refferer, but not when requesting insecure content from a secure page
231 QUrl documentUrl = QUrl(QString(document->documentURI()));
232 if (documentUrl.scheme().toLower() == QString::fromLatin1("http") || scheme == QString::fromLatin1("https"))
233 request.setRawHeader("Referer", documentUrl.toEncoded());
234
235 // Set the user agent
236 request.setRawHeader("User-Agent", frameLoader->userAgent(rUrl).utf8().data());
237 }
238
239 m_mediaPlayer->setMedia(QMediaContent(request));
240 } else {
241 // Otherwise, just use the URL
242 m_mediaPlayer->setMedia(QMediaContent(rUrl));
243 }
244
245 // Set the current volume and mute status
246 // We get these from the element, rather than the player, in case we have
247 // transitioned from a media engine which doesn't support muting, to a media
248 // engine which does.
249 m_mediaPlayer->setMuted(element->muted());
250 m_mediaPlayer->setVolume(static_cast<int>(element->volume() * 100.0));
251
252 // Don't send PlaybackChanged notification for pre-roll.
253 m_suppressNextPlaybackChanged = true;
254
255 // Setting a media source will start loading the media, but we need
256 // to pre-roll as well to get video size-hints and buffer-status
257 if (element->paused())
258 m_mediaPlayer->pause();
259 else
260 m_mediaPlayer->play();
261 }
262
resumeLoad()263 void MediaPlayerPrivateQt::resumeLoad()
264 {
265 m_delayingLoad = false;
266
267 if (!m_mediaUrl.isNull())
268 commitLoad(m_mediaUrl);
269 }
270
cancelLoad()271 void MediaPlayerPrivateQt::cancelLoad()
272 {
273 m_mediaPlayer->setMedia(QMediaContent());
274 updateStates();
275 }
276
prepareToPlay()277 void MediaPlayerPrivateQt::prepareToPlay()
278 {
279 if (m_mediaPlayer->media().isNull() || m_delayingLoad)
280 resumeLoad();
281 }
282
play()283 void MediaPlayerPrivateQt::play()
284 {
285 if (m_mediaPlayer->state() != QMediaPlayer::PlayingState)
286 m_mediaPlayer->play();
287 }
288
pause()289 void MediaPlayerPrivateQt::pause()
290 {
291 if (m_mediaPlayer->state() == QMediaPlayer::PlayingState)
292 m_mediaPlayer->pause();
293 }
294
paused() const295 bool MediaPlayerPrivateQt::paused() const
296 {
297 return (m_mediaPlayer->state() != QMediaPlayer::PlayingState);
298 }
299
seek(float position)300 void MediaPlayerPrivateQt::seek(float position)
301 {
302 if (!m_mediaPlayer->isSeekable())
303 return;
304
305 if (m_mediaPlayerControl && !m_mediaPlayerControl->availablePlaybackRanges().contains(position * 1000))
306 return;
307
308 m_isSeeking = true;
309 m_mediaPlayer->setPosition(static_cast<qint64>(position * 1000));
310 }
311
seeking() const312 bool MediaPlayerPrivateQt::seeking() const
313 {
314 return m_isSeeking;
315 }
316
duration() const317 float MediaPlayerPrivateQt::duration() const
318 {
319 if (m_readyState < MediaPlayer::HaveMetadata)
320 return 0.0f;
321
322 float duration = m_mediaPlayer->duration() / 1000.0f;
323
324 // We are streaming
325 if (duration <= 0.0f)
326 duration = std::numeric_limits<float>::infinity();
327
328 return duration;
329 }
330
currentTime() const331 float MediaPlayerPrivateQt::currentTime() const
332 {
333 return m_mediaPlayer->position() / 1000.0f;
334 }
335
buffered() const336 PassRefPtr<TimeRanges> MediaPlayerPrivateQt::buffered() const
337 {
338 RefPtr<TimeRanges> buffered = TimeRanges::create();
339
340 if (!m_mediaPlayerControl)
341 return buffered;
342
343 QMediaTimeRange playbackRanges = m_mediaPlayerControl->availablePlaybackRanges();
344
345 foreach (const QMediaTimeInterval interval, playbackRanges.intervals()) {
346 float rangeMin = static_cast<float>(interval.start()) / 1000.0f;
347 float rangeMax = static_cast<float>(interval.end()) / 1000.0f;
348 buffered->add(rangeMin, rangeMax);
349 }
350
351 return buffered.release();
352 }
353
maxTimeSeekable() const354 float MediaPlayerPrivateQt::maxTimeSeekable() const
355 {
356 if (!m_mediaPlayerControl)
357 return 0;
358
359 return static_cast<float>(m_mediaPlayerControl->availablePlaybackRanges().latestTime()) / 1000.0f;
360 }
361
bytesLoaded() const362 unsigned MediaPlayerPrivateQt::bytesLoaded() const
363 {
364 QLatin1String bytesLoadedKey("bytes-loaded");
365 if (m_mediaPlayer->availableExtendedMetaData().contains(bytesLoadedKey))
366 return m_mediaPlayer->extendedMetaData(bytesLoadedKey).toInt();
367
368 return m_mediaPlayer->bufferStatus();
369 }
370
totalBytes() const371 unsigned MediaPlayerPrivateQt::totalBytes() const
372 {
373 if (m_mediaPlayer->availableMetaData().contains(QtMultimediaKit::Size))
374 return m_mediaPlayer->metaData(QtMultimediaKit::Size).toInt();
375
376 return 100;
377 }
378
setPreload(MediaPlayer::Preload preload)379 void MediaPlayerPrivateQt::setPreload(MediaPlayer::Preload preload)
380 {
381 m_preload = preload;
382 if (m_delayingLoad && m_preload != MediaPlayer::None)
383 resumeLoad();
384 }
385
setRate(float rate)386 void MediaPlayerPrivateQt::setRate(float rate)
387 {
388 m_mediaPlayer->setPlaybackRate(rate);
389 }
390
setVolume(float volume)391 void MediaPlayerPrivateQt::setVolume(float volume)
392 {
393 m_mediaPlayer->setVolume(static_cast<int>(volume * 100.0));
394 }
395
supportsMuting() const396 bool MediaPlayerPrivateQt::supportsMuting() const
397 {
398 return true;
399 }
400
setMuted(bool muted)401 void MediaPlayerPrivateQt::setMuted(bool muted)
402 {
403 m_mediaPlayer->setMuted(muted);
404 }
405
networkState() const406 MediaPlayer::NetworkState MediaPlayerPrivateQt::networkState() const
407 {
408 return m_networkState;
409 }
410
readyState() const411 MediaPlayer::ReadyState MediaPlayerPrivateQt::readyState() const
412 {
413 return m_readyState;
414 }
415
setVisible(bool visible)416 void MediaPlayerPrivateQt::setVisible(bool visible)
417 {
418 m_isVisible = visible;
419 }
420
mediaStatusChanged(QMediaPlayer::MediaStatus)421 void MediaPlayerPrivateQt::mediaStatusChanged(QMediaPlayer::MediaStatus)
422 {
423 updateStates();
424 }
425
handleError(QMediaPlayer::Error)426 void MediaPlayerPrivateQt::handleError(QMediaPlayer::Error)
427 {
428 updateStates();
429 }
430
stateChanged(QMediaPlayer::State)431 void MediaPlayerPrivateQt::stateChanged(QMediaPlayer::State)
432 {
433 if (!m_suppressNextPlaybackChanged)
434 m_webCorePlayer->playbackStateChanged();
435 else
436 m_suppressNextPlaybackChanged = false;
437 }
438
nativeSizeChanged(const QSizeF & size)439 void MediaPlayerPrivateQt::nativeSizeChanged(const QSizeF& size)
440 {
441 LOG(Media, "MediaPlayerPrivateQt::naturalSizeChanged(%dx%d)",
442 size.toSize().width(), size.toSize().height());
443
444 if (!size.isValid())
445 return;
446
447 m_naturalSize = size.toSize();
448 m_webCorePlayer->sizeChanged();
449 }
450
positionChanged(qint64)451 void MediaPlayerPrivateQt::positionChanged(qint64)
452 {
453 // Only propagate this event if we are seeking
454 if (m_isSeeking) {
455 m_isSeeking = false;
456 m_webCorePlayer->timeChanged();
457 }
458 }
459
bufferStatusChanged(int)460 void MediaPlayerPrivateQt::bufferStatusChanged(int)
461 {
462 notImplemented();
463 }
464
durationChanged(qint64)465 void MediaPlayerPrivateQt::durationChanged(qint64)
466 {
467 m_webCorePlayer->durationChanged();
468 }
469
volumeChanged(int volume)470 void MediaPlayerPrivateQt::volumeChanged(int volume)
471 {
472 m_webCorePlayer->volumeChanged(static_cast<float>(volume) / 100.0);
473 }
474
mutedChanged(bool muted)475 void MediaPlayerPrivateQt::mutedChanged(bool muted)
476 {
477 m_webCorePlayer->muteChanged(muted);
478 }
479
updateStates()480 void MediaPlayerPrivateQt::updateStates()
481 {
482 // Store the old states so that we can detect a change and raise change events
483 MediaPlayer::NetworkState oldNetworkState = m_networkState;
484 MediaPlayer::ReadyState oldReadyState = m_readyState;
485
486 QMediaPlayer::MediaStatus currentStatus = m_mediaPlayer->mediaStatus();
487 QMediaPlayer::Error currentError = m_mediaPlayer->error();
488
489 if (currentError != QMediaPlayer::NoError) {
490 m_readyState = MediaPlayer::HaveNothing;
491 if (currentError == QMediaPlayer::FormatError)
492 m_networkState = MediaPlayer::FormatError;
493 else
494 m_networkState = MediaPlayer::NetworkError;
495 } else if (currentStatus == QMediaPlayer::UnknownMediaStatus
496 || currentStatus == QMediaPlayer::NoMedia) {
497 m_networkState = MediaPlayer::Idle;
498 m_readyState = MediaPlayer::HaveNothing;
499 } else if (currentStatus == QMediaPlayer::LoadingMedia) {
500 m_networkState = MediaPlayer::Loading;
501 m_readyState = MediaPlayer::HaveNothing;
502 } else if (currentStatus == QMediaPlayer::LoadedMedia) {
503 m_networkState = MediaPlayer::Loading;
504 m_readyState = MediaPlayer::HaveMetadata;
505 } else if (currentStatus == QMediaPlayer::BufferingMedia) {
506 m_networkState = MediaPlayer::Loading;
507 m_readyState = MediaPlayer::HaveFutureData;
508 } else if (currentStatus == QMediaPlayer::StalledMedia) {
509 m_networkState = MediaPlayer::Loading;
510 m_readyState = MediaPlayer::HaveCurrentData;
511 } else if (currentStatus == QMediaPlayer::BufferedMedia
512 || currentStatus == QMediaPlayer::EndOfMedia) {
513 m_networkState = MediaPlayer::Loaded;
514 m_readyState = MediaPlayer::HaveEnoughData;
515 } else if (currentStatus == QMediaPlayer::InvalidMedia) {
516 m_networkState = MediaPlayer::NetworkError;
517 m_readyState = MediaPlayer::HaveNothing;
518 }
519
520 // Log the state changes and raise the state change events
521 // NB: The readyStateChanged event must come before the networkStateChanged event.
522 // Breaking this invariant will cause the resource selection algorithm for multiple
523 // sources to fail.
524 if (m_readyState != oldReadyState)
525 m_webCorePlayer->readyStateChanged();
526
527 if (m_networkState != oldNetworkState)
528 m_webCorePlayer->networkStateChanged();
529 }
530
setSize(const IntSize & size)531 void MediaPlayerPrivateQt::setSize(const IntSize& size)
532 {
533 LOG(Media, "MediaPlayerPrivateQt::setSize(%dx%d)",
534 size.width(), size.height());
535
536 if (size == m_currentSize)
537 return;
538
539 m_currentSize = size;
540 m_videoItem->setSize(QSizeF(QSize(size)));
541 }
542
naturalSize() const543 IntSize MediaPlayerPrivateQt::naturalSize() const
544 {
545 if (!hasVideo() || m_readyState < MediaPlayer::HaveMetadata) {
546 LOG(Media, "MediaPlayerPrivateQt::naturalSize() -> 0x0 (!hasVideo || !haveMetaData)");
547 return IntSize();
548 }
549
550 LOG(Media, "MediaPlayerPrivateQt::naturalSize() -> %dx%d (m_naturalSize)",
551 m_naturalSize.width(), m_naturalSize.height());
552
553 return m_naturalSize;
554 }
555
removeVideoItem()556 void MediaPlayerPrivateQt::removeVideoItem()
557 {
558 m_oldNaturalSize = m_naturalSize;
559 m_mediaPlayer->setVideoOutput(static_cast<QGraphicsVideoItem*>(0));
560 m_videoScene->removeItem(m_videoItem);
561 }
562
restoreVideoItem()563 void MediaPlayerPrivateQt::restoreVideoItem()
564 {
565 m_mediaPlayer->setVideoOutput(m_videoItem);
566 m_videoScene->addItem(m_videoItem);
567 // FIXME: a qtmobility bug, need to reset the size when restore the videoitem, otherwise the size is 0
568 // http://bugreports.qt.nokia.com/browse/QTMOBILITY-971
569 nativeSizeChanged(QSize(m_oldNaturalSize));
570 }
571
paint(GraphicsContext * context,const IntRect & rect)572 void MediaPlayerPrivateQt::paint(GraphicsContext* context, const IntRect& rect)
573 {
574 #if USE(ACCELERATED_COMPOSITING)
575 if (m_composited)
576 return;
577 #endif
578 if (context->paintingDisabled())
579 return;
580
581 if (!m_isVisible)
582 return;
583
584 QPainter* painter = context->platformContext();
585 m_videoScene->render(painter, QRectF(QRect(rect)), m_videoItem->sceneBoundingRect());
586 }
587
paintCurrentFrameInContext(GraphicsContext * context,const IntRect & rect)588 void MediaPlayerPrivateQt::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& rect)
589 {
590 if (context->paintingDisabled())
591 return;
592
593 if (!m_isVisible)
594 return;
595
596 // Grab the painter and widget
597 QPainter* painter = context->platformContext();
598
599 // Render the video, using the item as it might not be in the scene
600 m_videoItem->paint(painter, 0, 0);
601 }
602
repaint()603 void MediaPlayerPrivateQt::repaint()
604 {
605 m_webCorePlayer->repaint();
606 }
607
608 #if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
609
610 class TextureMapperVideoLayerQt : public virtual TextureMapperMediaLayer {
611 public:
TextureMapperVideoLayerQt(QGraphicsVideoItem * videoItem)612 TextureMapperVideoLayerQt(QGraphicsVideoItem* videoItem)
613 : m_videoItem(videoItem)
614 {
615 }
616
setPlatformLayerClient(TextureMapperLayerClient * client)617 virtual void setPlatformLayerClient(TextureMapperLayerClient* client)
618 {
619 m_client = client;
620 }
621
paint(GraphicsContext * context)622 virtual void paint(GraphicsContext* context)
623 {
624 if (!m_videoItem)
625 return;
626
627 QStyleOptionGraphicsItem opt;
628 opt.exposedRect = m_videoItem.data()->sceneBoundingRect();
629 opt.rect = opt.exposedRect.toRect();
630 m_videoItem.data()->paint(context->platformContext(), &opt);
631 }
632
size() const633 virtual IntSize size() const
634 {
635 return m_videoItem ? IntSize(m_videoItem.data()->size().width(), m_videoItem.data()->size().height()) : IntSize();
636 }
637
638 QWeakPointer<QGraphicsVideoItem> m_videoItem;
639 TextureMapperLayerClient* m_client;
640 };
641
642
acceleratedRenderingStateChanged()643 void MediaPlayerPrivateQt::acceleratedRenderingStateChanged()
644 {
645 MediaPlayerClient* client = m_webCorePlayer->mediaPlayerClient();
646 bool composited = client->mediaPlayerRenderingCanBeAccelerated(m_webCorePlayer);
647 if (composited == m_composited)
648 return;
649
650 m_composited = composited;
651 if (composited)
652 m_platformLayer = new TextureMapperVideoLayerQt(m_videoItem);
653 }
654
platformLayer() const655 PlatformLayer* MediaPlayerPrivateQt::platformLayer() const
656 {
657 return m_composited ? m_platformLayer.get() : 0;
658 }
659 #endif
660
platformMedia() const661 PlatformMedia MediaPlayerPrivateQt::platformMedia() const
662 {
663 PlatformMedia pm;
664 pm.type = PlatformMedia::QtMediaPlayerType;
665 pm.media.qtMediaPlayer = const_cast<MediaPlayerPrivateQt*>(this);
666 return pm;
667 }
668
669 } // namespace WebCore
670
671 #include "moc_MediaPlayerPrivateQt.cpp"
672