Home | History | Annotate | Download | only in src
      1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "config.h"
      6 #include "WebMediaPlayerClientImpl.h"
      7 
      8 #if ENABLE(VIDEO)
      9 
     10 #include "Frame.h"
     11 #include "GraphicsContext.h"
     12 #include "HTMLMediaElement.h"
     13 #include "IntSize.h"
     14 #include "KURL.h"
     15 #include "MediaPlayer.h"
     16 #include "NotImplemented.h"
     17 #include "RenderView.h"
     18 #include "TimeRanges.h"
     19 #include "VideoLayerChromium.h"
     20 
     21 #if USE(ACCELERATED_COMPOSITING)
     22 #include "RenderLayerCompositor.h"
     23 #endif
     24 
     25 #include "VideoFrameChromium.h"
     26 #include "VideoFrameChromiumImpl.h"
     27 #include "WebCanvas.h"
     28 #include "WebCString.h"
     29 #include "WebFrameClient.h"
     30 #include "WebFrameImpl.h"
     31 #include "WebKit.h"
     32 #include "WebKitClient.h"
     33 #include "WebMediaElement.h"
     34 #include "WebMediaPlayer.h"
     35 #include "WebMimeRegistry.h"
     36 #include "WebRect.h"
     37 #include "WebSize.h"
     38 #include "WebString.h"
     39 #include "WebURL.h"
     40 #include "WebViewImpl.h"
     41 
     42 // WebCommon.h defines WEBKIT_USING_SKIA so this has to be included last.
     43 #if WEBKIT_USING_SKIA
     44 #include "PlatformContextSkia.h"
     45 #endif
     46 
     47 #include <wtf/Assertions.h>
     48 #include <wtf/text/CString.h>
     49 
     50 using namespace WebCore;
     51 
     52 namespace WebKit {
     53 
     54 static WebMediaPlayer* createWebMediaPlayer(
     55     WebMediaPlayerClient* client, Frame* frame)
     56 {
     57     WebFrameImpl* webFrame = WebFrameImpl::fromFrame(frame);
     58 
     59     if (!webFrame->client())
     60         return 0;
     61     return webFrame->client()->createMediaPlayer(webFrame, client);
     62 }
     63 
     64 bool WebMediaPlayerClientImpl::m_isEnabled = false;
     65 
     66 bool WebMediaPlayerClientImpl::isEnabled()
     67 {
     68     return m_isEnabled;
     69 }
     70 
     71 void WebMediaPlayerClientImpl::setIsEnabled(bool isEnabled)
     72 {
     73     m_isEnabled = isEnabled;
     74 }
     75 
     76 void WebMediaPlayerClientImpl::registerSelf(MediaEngineRegistrar registrar)
     77 {
     78     if (m_isEnabled) {
     79         registrar(WebMediaPlayerClientImpl::create,
     80                   WebMediaPlayerClientImpl::getSupportedTypes,
     81                   WebMediaPlayerClientImpl::supportsType,
     82                   0,
     83                   0,
     84                   0);
     85     }
     86 }
     87 
     88 WebMediaPlayerClientImpl* WebMediaPlayerClientImpl::fromMediaElement(const WebMediaElement* element)
     89 {
     90     PlatformMedia pm = element->constUnwrap<HTMLMediaElement>()->platformMedia();
     91     return static_cast<WebMediaPlayerClientImpl*>(pm.media.chromiumMediaPlayer);
     92 }
     93 
     94 WebMediaPlayer* WebMediaPlayerClientImpl::mediaPlayer() const
     95 {
     96     return m_webMediaPlayer.get();
     97 }
     98 
     99 // WebMediaPlayerClient --------------------------------------------------------
    100 
    101 WebMediaPlayerClientImpl::~WebMediaPlayerClientImpl()
    102 {
    103     // VideoLayerChromium may outlive this object so make sure all frames are
    104     // released.
    105 #if USE(ACCELERATED_COMPOSITING)
    106     if (m_videoLayer.get())
    107         m_videoLayer->releaseCurrentFrame();
    108 #endif
    109 }
    110 
    111 void WebMediaPlayerClientImpl::networkStateChanged()
    112 {
    113     ASSERT(m_mediaPlayer);
    114     m_mediaPlayer->networkStateChanged();
    115 }
    116 
    117 void WebMediaPlayerClientImpl::readyStateChanged()
    118 {
    119     ASSERT(m_mediaPlayer);
    120     m_mediaPlayer->readyStateChanged();
    121 #if USE(ACCELERATED_COMPOSITING)
    122     if (hasVideo() && supportsAcceleratedRendering() && !m_videoLayer.get())
    123         m_videoLayer = VideoLayerChromium::create(0, this);
    124 #endif
    125 }
    126 
    127 void WebMediaPlayerClientImpl::volumeChanged(float newVolume)
    128 {
    129     ASSERT(m_mediaPlayer);
    130     m_mediaPlayer->volumeChanged(newVolume);
    131 }
    132 
    133 void WebMediaPlayerClientImpl::muteChanged(bool newMute)
    134 {
    135     ASSERT(m_mediaPlayer);
    136     m_mediaPlayer->muteChanged(newMute);
    137 }
    138 
    139 void WebMediaPlayerClientImpl::timeChanged()
    140 {
    141     ASSERT(m_mediaPlayer);
    142     m_mediaPlayer->timeChanged();
    143 }
    144 
    145 void WebMediaPlayerClientImpl::repaint()
    146 {
    147     ASSERT(m_mediaPlayer);
    148 #if USE(ACCELERATED_COMPOSITING)
    149     if (m_videoLayer.get() && supportsAcceleratedRendering())
    150         m_videoLayer->setNeedsDisplay(IntRect(0, 0, m_videoLayer->bounds().width(), m_videoLayer->bounds().height()));
    151 #endif
    152     m_mediaPlayer->repaint();
    153 }
    154 
    155 void WebMediaPlayerClientImpl::durationChanged()
    156 {
    157     ASSERT(m_mediaPlayer);
    158     m_mediaPlayer->durationChanged();
    159 }
    160 
    161 void WebMediaPlayerClientImpl::rateChanged()
    162 {
    163     ASSERT(m_mediaPlayer);
    164     m_mediaPlayer->rateChanged();
    165 }
    166 
    167 void WebMediaPlayerClientImpl::sizeChanged()
    168 {
    169     ASSERT(m_mediaPlayer);
    170     m_mediaPlayer->sizeChanged();
    171 }
    172 
    173 void WebMediaPlayerClientImpl::sawUnsupportedTracks()
    174 {
    175     ASSERT(m_mediaPlayer);
    176     m_mediaPlayer->mediaPlayerClient()->mediaPlayerSawUnsupportedTracks(m_mediaPlayer);
    177 }
    178 
    179 float WebMediaPlayerClientImpl::volume() const
    180 {
    181     if (m_mediaPlayer)
    182         return m_mediaPlayer->volume();
    183     return 0.0f;
    184 }
    185 
    186 void WebMediaPlayerClientImpl::playbackStateChanged()
    187 {
    188     ASSERT(m_mediaPlayer);
    189     m_mediaPlayer->playbackStateChanged();
    190 }
    191 
    192 WebMediaPlayer::Preload WebMediaPlayerClientImpl::preload() const
    193 {
    194     if (m_mediaPlayer)
    195         return static_cast<WebMediaPlayer::Preload>(m_mediaPlayer->preload());
    196     return static_cast<WebMediaPlayer::Preload>(m_preload);
    197 }
    198 
    199 // MediaPlayerPrivateInterface -------------------------------------------------
    200 
    201 void WebMediaPlayerClientImpl::load(const String& url)
    202 {
    203     m_url = url;
    204 
    205     // Video frame object is owned by WebMediaPlayer. Before destroying
    206     // WebMediaPlayer all frames need to be released.
    207 #if USE(ACCELERATED_COMPOSITING)
    208     if (m_videoLayer.get())
    209         m_videoLayer->releaseCurrentFrame();
    210 #endif
    211 
    212     if (m_preload == MediaPlayer::None) {
    213         m_webMediaPlayer.clear();
    214         m_delayingLoad = true;
    215     } else
    216         loadInternal();
    217 }
    218 
    219 void WebMediaPlayerClientImpl::loadInternal()
    220 {
    221     Frame* frame = static_cast<HTMLMediaElement*>(m_mediaPlayer->mediaPlayerClient())->document()->frame();
    222     m_webMediaPlayer.set(createWebMediaPlayer(this, frame));
    223     if (m_webMediaPlayer.get())
    224         m_webMediaPlayer->load(KURL(ParsedURLString, m_url));
    225 }
    226 
    227 void WebMediaPlayerClientImpl::cancelLoad()
    228 {
    229     if (m_webMediaPlayer.get())
    230         m_webMediaPlayer->cancelLoad();
    231 }
    232 
    233 #if USE(ACCELERATED_COMPOSITING)
    234 PlatformLayer* WebMediaPlayerClientImpl::platformLayer() const
    235 {
    236     ASSERT(m_supportsAcceleratedCompositing);
    237     return m_videoLayer.get();
    238 }
    239 #endif
    240 
    241 PlatformMedia WebMediaPlayerClientImpl::platformMedia() const
    242 {
    243     PlatformMedia pm;
    244     pm.type = PlatformMedia::ChromiumMediaPlayerType;
    245     pm.media.chromiumMediaPlayer = const_cast<WebMediaPlayerClientImpl*>(this);
    246     return pm;
    247 }
    248 
    249 void WebMediaPlayerClientImpl::play()
    250 {
    251     if (m_webMediaPlayer.get())
    252         m_webMediaPlayer->play();
    253 }
    254 
    255 void WebMediaPlayerClientImpl::pause()
    256 {
    257     if (m_webMediaPlayer.get())
    258         m_webMediaPlayer->pause();
    259 }
    260 
    261 void WebMediaPlayerClientImpl::prepareToPlay()
    262 {
    263     if (m_delayingLoad)
    264         startDelayedLoad();
    265 }
    266 
    267 IntSize WebMediaPlayerClientImpl::naturalSize() const
    268 {
    269     if (m_webMediaPlayer.get())
    270         return m_webMediaPlayer->naturalSize();
    271     return IntSize();
    272 }
    273 
    274 bool WebMediaPlayerClientImpl::hasVideo() const
    275 {
    276     if (m_webMediaPlayer.get())
    277         return m_webMediaPlayer->hasVideo();
    278     return false;
    279 }
    280 
    281 bool WebMediaPlayerClientImpl::hasAudio() const
    282 {
    283     if (m_webMediaPlayer.get())
    284         return m_webMediaPlayer->hasAudio();
    285     return false;
    286 }
    287 
    288 void WebMediaPlayerClientImpl::setVisible(bool visible)
    289 {
    290     if (m_webMediaPlayer.get())
    291         m_webMediaPlayer->setVisible(visible);
    292 }
    293 
    294 float WebMediaPlayerClientImpl::duration() const
    295 {
    296     if (m_webMediaPlayer.get())
    297         return m_webMediaPlayer->duration();
    298     return 0.0f;
    299 }
    300 
    301 float WebMediaPlayerClientImpl::currentTime() const
    302 {
    303     if (m_webMediaPlayer.get())
    304         return m_webMediaPlayer->currentTime();
    305     return 0.0f;
    306 }
    307 
    308 void WebMediaPlayerClientImpl::seek(float time)
    309 {
    310     if (m_webMediaPlayer.get())
    311         m_webMediaPlayer->seek(time);
    312 }
    313 
    314 bool WebMediaPlayerClientImpl::seeking() const
    315 {
    316     if (m_webMediaPlayer.get())
    317         return m_webMediaPlayer->seeking();
    318     return false;
    319 }
    320 
    321 void WebMediaPlayerClientImpl::setEndTime(float time)
    322 {
    323     if (m_webMediaPlayer.get())
    324         m_webMediaPlayer->setEndTime(time);
    325 }
    326 
    327 void WebMediaPlayerClientImpl::setRate(float rate)
    328 {
    329     if (m_webMediaPlayer.get())
    330         m_webMediaPlayer->setRate(rate);
    331 }
    332 
    333 bool WebMediaPlayerClientImpl::paused() const
    334 {
    335     if (m_webMediaPlayer.get())
    336         return m_webMediaPlayer->paused();
    337     return false;
    338 }
    339 
    340 bool WebMediaPlayerClientImpl::supportsFullscreen() const
    341 {
    342     if (m_webMediaPlayer.get())
    343         return m_webMediaPlayer->supportsFullscreen();
    344     return false;
    345 }
    346 
    347 bool WebMediaPlayerClientImpl::supportsSave() const
    348 {
    349     if (m_webMediaPlayer.get())
    350         return m_webMediaPlayer->supportsSave();
    351     return false;
    352 }
    353 
    354 void WebMediaPlayerClientImpl::setVolume(float volume)
    355 {
    356     if (m_webMediaPlayer.get())
    357         m_webMediaPlayer->setVolume(volume);
    358 }
    359 
    360 MediaPlayer::NetworkState WebMediaPlayerClientImpl::networkState() const
    361 {
    362     if (m_webMediaPlayer.get())
    363         return static_cast<MediaPlayer::NetworkState>(m_webMediaPlayer->networkState());
    364     return MediaPlayer::Empty;
    365 }
    366 
    367 MediaPlayer::ReadyState WebMediaPlayerClientImpl::readyState() const
    368 {
    369     if (m_webMediaPlayer.get())
    370         return static_cast<MediaPlayer::ReadyState>(m_webMediaPlayer->readyState());
    371     return MediaPlayer::HaveNothing;
    372 }
    373 
    374 float WebMediaPlayerClientImpl::maxTimeSeekable() const
    375 {
    376     if (m_webMediaPlayer.get())
    377         return m_webMediaPlayer->maxTimeSeekable();
    378     return 0.0f;
    379 }
    380 
    381 PassRefPtr<TimeRanges> WebMediaPlayerClientImpl::buffered() const
    382 {
    383     if (m_webMediaPlayer.get()) {
    384         const WebTimeRanges& webRanges = m_webMediaPlayer->buffered();
    385 
    386         // FIXME: Save the time ranges in a member variable and update it when needed.
    387         RefPtr<TimeRanges> ranges = TimeRanges::create();
    388         for (size_t i = 0; i < webRanges.size(); ++i)
    389             ranges->add(webRanges[i].start, webRanges[i].end);
    390         return ranges.release();
    391     }
    392     return TimeRanges::create();
    393 }
    394 
    395 int WebMediaPlayerClientImpl::dataRate() const
    396 {
    397     if (m_webMediaPlayer.get())
    398         return m_webMediaPlayer->dataRate();
    399     return 0;
    400 }
    401 
    402 bool WebMediaPlayerClientImpl::totalBytesKnown() const
    403 {
    404     if (m_webMediaPlayer.get())
    405         return m_webMediaPlayer->totalBytesKnown();
    406     return false;
    407 }
    408 
    409 unsigned WebMediaPlayerClientImpl::totalBytes() const
    410 {
    411     if (m_webMediaPlayer.get())
    412         return static_cast<unsigned>(m_webMediaPlayer->totalBytes());
    413     return 0;
    414 }
    415 
    416 unsigned WebMediaPlayerClientImpl::bytesLoaded() const
    417 {
    418     if (m_webMediaPlayer.get())
    419         return static_cast<unsigned>(m_webMediaPlayer->bytesLoaded());
    420     return 0;
    421 }
    422 
    423 void WebMediaPlayerClientImpl::setSize(const IntSize& size)
    424 {
    425     if (m_webMediaPlayer.get())
    426         m_webMediaPlayer->setSize(WebSize(size.width(), size.height()));
    427 }
    428 
    429 void WebMediaPlayerClientImpl::paint(GraphicsContext* context, const IntRect& rect)
    430 {
    431 #if USE(ACCELERATED_COMPOSITING)
    432     // If we are using GPU to render video, ignore requests to paint frames into
    433     // canvas because it will be taken care of by VideoLayerChromium.
    434     if (acceleratedRenderingInUse())
    435         return;
    436 #endif
    437     paintCurrentFrameInContext(context, rect);
    438 }
    439 
    440 void WebMediaPlayerClientImpl::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& rect)
    441 {
    442     // Normally GraphicsContext operations do nothing when painting is disabled.
    443     // Since we're accessing platformContext() directly we have to manually
    444     // check.
    445     if (m_webMediaPlayer.get() && !context->paintingDisabled()) {
    446 #if WEBKIT_USING_SKIA
    447         PlatformGraphicsContext* platformContext = context->platformContext();
    448         WebCanvas* canvas = platformContext->canvas();
    449 
    450         canvas->saveLayerAlpha(0, platformContext->getNormalizedAlpha());
    451 
    452         m_webMediaPlayer->paint(canvas, rect);
    453 
    454         canvas->restore();
    455 #elif WEBKIT_USING_CG
    456         m_webMediaPlayer->paint(context->platformContext(), rect);
    457 #else
    458         notImplemented();
    459 #endif
    460     }
    461 }
    462 
    463 void WebMediaPlayerClientImpl::setPreload(MediaPlayer::Preload preload)
    464 {
    465     m_preload = preload;
    466 
    467     if (m_webMediaPlayer.get())
    468         m_webMediaPlayer->setPreload(static_cast<WebMediaPlayer::Preload>(preload));
    469 
    470     if (m_delayingLoad && m_preload != MediaPlayer::None)
    471         startDelayedLoad();
    472 }
    473 
    474 bool WebMediaPlayerClientImpl::hasSingleSecurityOrigin() const
    475 {
    476     if (m_webMediaPlayer.get())
    477         return m_webMediaPlayer->hasSingleSecurityOrigin();
    478     return false;
    479 }
    480 
    481 MediaPlayer::MovieLoadType WebMediaPlayerClientImpl::movieLoadType() const
    482 {
    483     if (m_webMediaPlayer.get())
    484         return static_cast<MediaPlayer::MovieLoadType>(
    485             m_webMediaPlayer->movieLoadType());
    486     return MediaPlayer::Unknown;
    487 }
    488 
    489 unsigned WebMediaPlayerClientImpl::decodedFrameCount() const
    490 {
    491     if (m_webMediaPlayer.get())
    492         return m_webMediaPlayer->decodedFrameCount();
    493     return 0;
    494 }
    495 
    496 unsigned WebMediaPlayerClientImpl::droppedFrameCount() const
    497 {
    498     if (m_webMediaPlayer.get())
    499         return m_webMediaPlayer->droppedFrameCount();
    500     return 0;
    501 }
    502 
    503 unsigned WebMediaPlayerClientImpl::audioDecodedByteCount() const
    504 {
    505     if (m_webMediaPlayer.get())
    506         return m_webMediaPlayer->audioDecodedByteCount();
    507     return 0;
    508 }
    509 
    510 unsigned WebMediaPlayerClientImpl::videoDecodedByteCount() const
    511 {
    512     if (m_webMediaPlayer.get())
    513         return m_webMediaPlayer->videoDecodedByteCount();
    514     return 0;
    515 }
    516 
    517 #if USE(ACCELERATED_COMPOSITING)
    518 bool WebMediaPlayerClientImpl::supportsAcceleratedRendering() const
    519 {
    520     return m_supportsAcceleratedCompositing;
    521 }
    522 
    523 bool WebMediaPlayerClientImpl::acceleratedRenderingInUse()
    524 {
    525     return m_videoLayer.get() && m_videoLayer->layerRenderer();
    526 }
    527 
    528 VideoFrameChromium* WebMediaPlayerClientImpl::getCurrentFrame()
    529 {
    530     VideoFrameChromium* videoFrame = 0;
    531     if (m_webMediaPlayer.get()) {
    532         WebVideoFrame* webkitVideoFrame = m_webMediaPlayer->getCurrentFrame();
    533         if (webkitVideoFrame)
    534             videoFrame = new VideoFrameChromiumImpl(webkitVideoFrame);
    535     }
    536     return videoFrame;
    537 }
    538 
    539 void WebMediaPlayerClientImpl::putCurrentFrame(VideoFrameChromium* videoFrame)
    540 {
    541     if (videoFrame) {
    542         if (m_webMediaPlayer.get()) {
    543             m_webMediaPlayer->putCurrentFrame(
    544                 VideoFrameChromiumImpl::toWebVideoFrame(videoFrame));
    545         }
    546         delete videoFrame;
    547     }
    548 }
    549 #endif
    550 
    551 MediaPlayerPrivateInterface* WebMediaPlayerClientImpl::create(MediaPlayer* player)
    552 {
    553     WebMediaPlayerClientImpl* client = new WebMediaPlayerClientImpl();
    554     client->m_mediaPlayer = player;
    555 
    556 #if USE(ACCELERATED_COMPOSITING)
    557     Frame* frame = static_cast<HTMLMediaElement*>(
    558         client->m_mediaPlayer->mediaPlayerClient())->document()->frame();
    559 
    560     // This does not actually check whether the hardware can support accelerated
    561     // compositing, but only if the flag is set. However, this is checked lazily
    562     // in WebViewImpl::setIsAcceleratedCompositingActive() and will fail there
    563     // if necessary.
    564     client->m_supportsAcceleratedCompositing =
    565         frame->contentRenderer()->compositor()->hasAcceleratedCompositing();
    566 #endif
    567 
    568     return client;
    569 }
    570 
    571 void WebMediaPlayerClientImpl::getSupportedTypes(HashSet<String>& supportedTypes)
    572 {
    573     // FIXME: integrate this list with WebMediaPlayerClientImpl::supportsType.
    574     notImplemented();
    575 }
    576 
    577 MediaPlayer::SupportsType WebMediaPlayerClientImpl::supportsType(const String& type,
    578                                                                  const String& codecs)
    579 {
    580     WebMimeRegistry::SupportsType supportsType =
    581         webKitClient()->mimeRegistry()->supportsMediaMIMEType(type, codecs);
    582 
    583     switch (supportsType) {
    584     default:
    585         ASSERT_NOT_REACHED();
    586     case WebMimeRegistry::IsNotSupported:
    587         return MediaPlayer::IsNotSupported;
    588     case WebMimeRegistry::IsSupported:
    589         return MediaPlayer::IsSupported;
    590     case WebMimeRegistry::MayBeSupported:
    591         return MediaPlayer::MayBeSupported;
    592     }
    593     return MediaPlayer::IsNotSupported;
    594 }
    595 
    596 void WebMediaPlayerClientImpl::startDelayedLoad()
    597 {
    598     ASSERT(m_delayingLoad);
    599     ASSERT(!m_webMediaPlayer.get());
    600 
    601     m_delayingLoad = false;
    602 
    603     loadInternal();
    604 }
    605 
    606 WebMediaPlayerClientImpl::WebMediaPlayerClientImpl()
    607     : m_mediaPlayer(0)
    608     , m_delayingLoad(false)
    609     , m_preload(MediaPlayer::MetaData)
    610 #if USE(ACCELERATED_COMPOSITING)
    611     , m_videoLayer(0)
    612     , m_supportsAcceleratedCompositing(false)
    613 #endif
    614 {
    615 }
    616 
    617 } // namespace WebKit
    618 
    619 #endif  // ENABLE(VIDEO)
    620