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 PassOwnPtr<MediaPlayerPrivateInterface> MediaPlayerPrivateQt::create(MediaPlayer* player)
62 {
63     return adoptPtr(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 || currentError == QMediaPlayer::ResourceError)
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::FormatError;
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