Home | History | Annotate | Download | only in qt
      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 
     61 MediaPlayerPrivateInterface* MediaPlayerPrivateQt::create(MediaPlayer* player)
     62 {
     63     return new MediaPlayerPrivateQt(player);
     64 }
     65 
     66 void MediaPlayerPrivateQt::registerMediaEngine(MediaEngineRegistrar registrar)
     67 {
     68     registrar(create, getSupportedTypes, supportsType, 0, 0, 0);
     69 }
     70 
     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 
     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 
    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 
    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 
    161 bool MediaPlayerPrivateQt::hasVideo() const
    162 {
    163     return m_mediaPlayer->isVideoAvailable();
    164 }
    165 
    166 bool MediaPlayerPrivateQt::hasAudio() const
    167 {
    168     return true;
    169 }
    170 
    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 
    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 
    263 void MediaPlayerPrivateQt::resumeLoad()
    264 {
    265     m_delayingLoad = false;
    266 
    267     if (!m_mediaUrl.isNull())
    268         commitLoad(m_mediaUrl);
    269 }
    270 
    271 void MediaPlayerPrivateQt::cancelLoad()
    272 {
    273     m_mediaPlayer->setMedia(QMediaContent());
    274     updateStates();
    275 }
    276 
    277 void MediaPlayerPrivateQt::prepareToPlay()
    278 {
    279     if (m_mediaPlayer->media().isNull() || m_delayingLoad)
    280         resumeLoad();
    281 }
    282 
    283 void MediaPlayerPrivateQt::play()
    284 {
    285     if (m_mediaPlayer->state() != QMediaPlayer::PlayingState)
    286         m_mediaPlayer->play();
    287 }
    288 
    289 void MediaPlayerPrivateQt::pause()
    290 {
    291     if (m_mediaPlayer->state() == QMediaPlayer::PlayingState)
    292         m_mediaPlayer->pause();
    293 }
    294 
    295 bool MediaPlayerPrivateQt::paused() const
    296 {
    297     return (m_mediaPlayer->state() != QMediaPlayer::PlayingState);
    298 }
    299 
    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 
    312 bool MediaPlayerPrivateQt::seeking() const
    313 {
    314     return m_isSeeking;
    315 }
    316 
    317 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 
    331 float MediaPlayerPrivateQt::currentTime() const
    332 {
    333     return m_mediaPlayer->position() / 1000.0f;
    334 }
    335 
    336 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 
    354 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 
    362 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 
    371 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 
    379 void MediaPlayerPrivateQt::setPreload(MediaPlayer::Preload preload)
    380 {
    381     m_preload = preload;
    382     if (m_delayingLoad && m_preload != MediaPlayer::None)
    383         resumeLoad();
    384 }
    385 
    386 void MediaPlayerPrivateQt::setRate(float rate)
    387 {
    388     m_mediaPlayer->setPlaybackRate(rate);
    389 }
    390 
    391 void MediaPlayerPrivateQt::setVolume(float volume)
    392 {
    393     m_mediaPlayer->setVolume(static_cast<int>(volume * 100.0));
    394 }
    395 
    396 bool MediaPlayerPrivateQt::supportsMuting() const
    397 {
    398     return true;
    399 }
    400 
    401 void MediaPlayerPrivateQt::setMuted(bool muted)
    402 {
    403     m_mediaPlayer->setMuted(muted);
    404 }
    405 
    406 MediaPlayer::NetworkState MediaPlayerPrivateQt::networkState() const
    407 {
    408     return m_networkState;
    409 }
    410 
    411 MediaPlayer::ReadyState MediaPlayerPrivateQt::readyState() const
    412 {
    413     return m_readyState;
    414 }
    415 
    416 void MediaPlayerPrivateQt::setVisible(bool visible)
    417 {
    418     m_isVisible = visible;
    419 }
    420 
    421 void MediaPlayerPrivateQt::mediaStatusChanged(QMediaPlayer::MediaStatus)
    422 {
    423     updateStates();
    424 }
    425 
    426 void MediaPlayerPrivateQt::handleError(QMediaPlayer::Error)
    427 {
    428     updateStates();
    429 }
    430 
    431 void MediaPlayerPrivateQt::stateChanged(QMediaPlayer::State)
    432 {
    433     if (!m_suppressNextPlaybackChanged)
    434         m_webCorePlayer->playbackStateChanged();
    435     else
    436         m_suppressNextPlaybackChanged = false;
    437 }
    438 
    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 
    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 
    460 void MediaPlayerPrivateQt::bufferStatusChanged(int)
    461 {
    462     notImplemented();
    463 }
    464 
    465 void MediaPlayerPrivateQt::durationChanged(qint64)
    466 {
    467     m_webCorePlayer->durationChanged();
    468 }
    469 
    470 void MediaPlayerPrivateQt::volumeChanged(int volume)
    471 {
    472     m_webCorePlayer->volumeChanged(static_cast<float>(volume) / 100.0);
    473 }
    474 
    475 void MediaPlayerPrivateQt::mutedChanged(bool muted)
    476 {
    477     m_webCorePlayer->muteChanged(muted);
    478 }
    479 
    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 
    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 
    543 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 
    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 
    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 
    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 
    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 
    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:
    612     TextureMapperVideoLayerQt(QGraphicsVideoItem* videoItem)
    613         : m_videoItem(videoItem)
    614     {
    615     }
    616 
    617     virtual void setPlatformLayerClient(TextureMapperLayerClient* client)
    618     {
    619         m_client = client;
    620     }
    621 
    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 
    633     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 
    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 
    655 PlatformLayer* MediaPlayerPrivateQt::platformLayer() const
    656 {
    657     return m_composited ? m_platformLayer.get() : 0;
    658 }
    659 #endif
    660 
    661 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