Home | History | Annotate | Download | only in graphics
      1 /*
      2  * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 
     28 #if ENABLE(VIDEO)
     29 #include "MediaPlayer.h"
     30 #include "MediaPlayerPrivate.h"
     31 
     32 #include "ContentType.h"
     33 #include "IntRect.h"
     34 #include "MIMETypeRegistry.h"
     35 #include "FrameView.h"
     36 #include "Frame.h"
     37 #include "Document.h"
     38 #include "TimeRanges.h"
     39 
     40 #if PLATFORM(MAC)
     41 #include "MediaPlayerPrivateQTKit.h"
     42 #elif OS(WINCE) && !PLATFORM(QT)
     43 #include "MediaPlayerPrivateWince.h"
     44 #elif PLATFORM(WIN)
     45 #include "MediaPlayerPrivateQuickTimeWin.h"
     46 #elif PLATFORM(GTK)
     47 #include "MediaPlayerPrivateGStreamer.h"
     48 #elif PLATFORM(QT)
     49 #include "MediaPlayerPrivatePhonon.h"
     50 #elif PLATFORM(CHROMIUM)
     51 #include "MediaPlayerPrivateChromium.h"
     52 #elif PLATFORM(ANDROID)
     53 #include "MediaPlayerPrivateAndroid.h"
     54 #endif
     55 
     56 namespace WebCore {
     57 
     58 // a null player to make MediaPlayer logic simpler
     59 
     60 class NullMediaPlayerPrivate : public MediaPlayerPrivateInterface {
     61 public:
     62     NullMediaPlayerPrivate(MediaPlayer*) { }
     63 
     64     virtual void load(const String&) { }
     65     virtual void cancelLoad() { }
     66 
     67     virtual void prepareToPlay() { }
     68     virtual void play() { }
     69     virtual void pause() { }
     70 
     71     virtual PlatformMedia platformMedia() const { return NoPlatformMedia; }
     72 
     73     virtual IntSize naturalSize() const { return IntSize(0, 0); }
     74 
     75     virtual bool hasVideo() const { return false; }
     76     virtual bool hasAudio() const { return false; }
     77 
     78     virtual void setVisible(bool) { }
     79 
     80     virtual float duration() const { return 0; }
     81 
     82     virtual float currentTime() const { return 0; }
     83     virtual void seek(float) { }
     84     virtual bool seeking() const { return false; }
     85 
     86     virtual void setRate(float) { }
     87     virtual void setPreservesPitch(bool) { }
     88     virtual bool paused() const { return false; }
     89 
     90     virtual void setVolume(float) { }
     91 
     92     virtual bool supportsMuting() const { return false; }
     93     virtual void setMuted(bool) { }
     94 
     95     virtual bool hasClosedCaptions() const { return false; }
     96     virtual void setClosedCaptionsVisible(bool) { };
     97 
     98     virtual MediaPlayer::NetworkState networkState() const { return MediaPlayer::Empty; }
     99     virtual MediaPlayer::ReadyState readyState() const { return MediaPlayer::HaveNothing; }
    100 
    101     virtual float maxTimeSeekable() const { return 0; }
    102     virtual PassRefPtr<TimeRanges> buffered() const { return TimeRanges::create(); }
    103 
    104     virtual unsigned totalBytes() const { return 0; }
    105     virtual unsigned bytesLoaded() const { return 0; }
    106 
    107     virtual void setSize(const IntSize&) { }
    108 
    109     virtual void paint(GraphicsContext*, const IntRect&) { }
    110 
    111     virtual bool canLoadPoster() const { return false; }
    112     virtual void setPoster(const String&) { }
    113 
    114 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
    115     virtual void deliverNotification(MediaPlayerProxyNotificationType) { }
    116     virtual void setMediaPlayerProxy(WebMediaPlayerProxy*) { }
    117 #endif
    118 
    119     virtual bool hasSingleSecurityOrigin() const { return true; }
    120 };
    121 
    122 static MediaPlayerPrivateInterface* createNullMediaPlayer(MediaPlayer* player)
    123 {
    124     return new NullMediaPlayerPrivate(player);
    125 }
    126 
    127 
    128 // engine support
    129 
    130 struct MediaPlayerFactory : Noncopyable {
    131     MediaPlayerFactory(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsTypeAndCodecs)
    132         : constructor(constructor)
    133         , getSupportedTypes(getSupportedTypes)
    134         , supportsTypeAndCodecs(supportsTypeAndCodecs)
    135     {
    136     }
    137 
    138     CreateMediaEnginePlayer constructor;
    139     MediaEngineSupportedTypes getSupportedTypes;
    140     MediaEngineSupportsType supportsTypeAndCodecs;
    141 };
    142 
    143 static void addMediaEngine(CreateMediaEnginePlayer, MediaEngineSupportedTypes, MediaEngineSupportsType);
    144 static MediaPlayerFactory* chooseBestEngineForTypeAndCodecs(const String& type, const String& codecs);
    145 
    146 static Vector<MediaPlayerFactory*>& installedMediaEngines()
    147 {
    148     DEFINE_STATIC_LOCAL(Vector<MediaPlayerFactory*>, installedEngines, ());
    149     static bool enginesQueried = false;
    150 
    151     if (!enginesQueried) {
    152         enginesQueried = true;
    153         MediaPlayerPrivate::registerMediaEngine(addMediaEngine);
    154 
    155         // register additional engines here
    156     }
    157 
    158     return installedEngines;
    159 }
    160 
    161 static void addMediaEngine(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsType)
    162 {
    163     ASSERT(constructor);
    164     ASSERT(getSupportedTypes);
    165     ASSERT(supportsType);
    166     installedMediaEngines().append(new MediaPlayerFactory(constructor, getSupportedTypes, supportsType));
    167 }
    168 
    169 static MediaPlayerFactory* chooseBestEngineForTypeAndCodecs(const String& type, const String& codecs)
    170 {
    171     Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
    172 
    173     if (engines.isEmpty())
    174         return 0;
    175 
    176     MediaPlayerFactory* engine = 0;
    177     MediaPlayer::SupportsType supported = MediaPlayer::IsNotSupported;
    178 
    179     unsigned count = engines.size();
    180     for (unsigned ndx = 0; ndx < count; ndx++) {
    181         MediaPlayer::SupportsType engineSupport = engines[ndx]->supportsTypeAndCodecs(type, codecs);
    182         if (engineSupport > supported) {
    183             supported = engineSupport;
    184             engine = engines[ndx];
    185         }
    186     }
    187 
    188     return engine;
    189 }
    190 
    191 // media player
    192 
    193 MediaPlayer::MediaPlayer(MediaPlayerClient* client)
    194     : m_mediaPlayerClient(client)
    195     , m_private(createNullMediaPlayer(this))
    196     , m_currentMediaEngine(0)
    197     , m_frameView(0)
    198     , m_visible(false)
    199     , m_rate(1.0f)
    200     , m_volume(1.0f)
    201     , m_muted(false)
    202     , m_preservesPitch(true)
    203     , m_autobuffer(false)
    204 #if PLATFORM(ANDROID)
    205     , m_mediaElementType(Video)
    206 #endif
    207 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
    208     , m_playerProxy(0)
    209 #endif
    210 {
    211 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
    212     Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
    213     if (!engines.isEmpty()) {
    214         m_currentMediaEngine = engines[0];
    215         m_private.clear();
    216         m_private.set(engines[0]->constructor(this));
    217     }
    218 #endif
    219 }
    220 
    221 MediaPlayer::~MediaPlayer()
    222 {
    223 }
    224 
    225 void MediaPlayer::load(const String& url, const ContentType& contentType)
    226 {
    227     String type = contentType.type();
    228     String codecs = contentType.parameter("codecs");
    229 
    230     // if we don't know the MIME type, see if the extension can help
    231     if (type.isEmpty() || type == "application/octet-stream" || type == "text/plain") {
    232         int pos = url.reverseFind('.');
    233         if (pos >= 0) {
    234             String extension = url.substring(pos + 1);
    235             String mediaType = MIMETypeRegistry::getMediaMIMETypeForExtension(extension);
    236             if (!mediaType.isEmpty())
    237                 type = mediaType;
    238         }
    239     }
    240 
    241     MediaPlayerFactory* engine = 0;
    242     if (!type.isEmpty())
    243         engine = chooseBestEngineForTypeAndCodecs(type, codecs);
    244 
    245     // if we didn't find an engine that claims the MIME type, just use the first engine
    246     if (!engine && !installedMediaEngines().isEmpty())
    247         engine = installedMediaEngines()[0];
    248 
    249     // don't delete and recreate the player unless it comes from a different engine
    250     if (engine && m_currentMediaEngine != engine) {
    251         m_currentMediaEngine = engine;
    252         m_private.clear();
    253         m_private.set(engine->constructor(this));
    254 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
    255         m_private->setMediaPlayerProxy(m_playerProxy);
    256 #endif
    257         m_private->setAutobuffer(autobuffer());
    258         m_private->setPreservesPitch(preservesPitch());
    259     }
    260 
    261     if (m_private)
    262         m_private->load(url);
    263     else
    264         m_private.set(createNullMediaPlayer(this));
    265 }
    266 
    267 bool MediaPlayer::hasAvailableVideoFrame() const
    268 {
    269     return m_private->hasAvailableVideoFrame();
    270 }
    271 
    272 bool MediaPlayer::canLoadPoster() const
    273 {
    274     return m_private->canLoadPoster();
    275 }
    276 
    277 void MediaPlayer::setPoster(const String& url)
    278 {
    279     m_private->setPoster(url);
    280 }
    281 
    282 void MediaPlayer::cancelLoad()
    283 {
    284     m_private->cancelLoad();
    285 }
    286 
    287 void MediaPlayer::prepareToPlay()
    288 {
    289     m_private->prepareToPlay();
    290 }
    291 
    292 void MediaPlayer::play()
    293 {
    294     m_private->play();
    295 }
    296 
    297 void MediaPlayer::pause()
    298 {
    299     m_private->pause();
    300 }
    301 
    302 float MediaPlayer::duration() const
    303 {
    304     return m_private->duration();
    305 }
    306 
    307 float MediaPlayer::startTime() const
    308 {
    309     return m_private->startTime();
    310 }
    311 
    312 float MediaPlayer::currentTime() const
    313 {
    314     return m_private->currentTime();
    315 }
    316 
    317 void MediaPlayer::seek(float time)
    318 {
    319     m_private->seek(time);
    320 }
    321 
    322 bool MediaPlayer::paused() const
    323 {
    324     return m_private->paused();
    325 }
    326 
    327 bool MediaPlayer::seeking() const
    328 {
    329     return m_private->seeking();
    330 }
    331 
    332 bool MediaPlayer::supportsFullscreen() const
    333 {
    334     return m_private->supportsFullscreen();
    335 }
    336 
    337 bool MediaPlayer::supportsSave() const
    338 {
    339     return m_private->supportsSave();
    340 }
    341 
    342 IntSize MediaPlayer::naturalSize()
    343 {
    344     return m_private->naturalSize();
    345 }
    346 
    347 bool MediaPlayer::hasVideo() const
    348 {
    349     return m_private->hasVideo();
    350 }
    351 
    352 bool MediaPlayer::hasAudio() const
    353 {
    354     return m_private->hasAudio();
    355 }
    356 
    357 bool MediaPlayer::inMediaDocument()
    358 {
    359     Frame* frame = m_frameView ? m_frameView->frame() : 0;
    360     Document* document = frame ? frame->document() : 0;
    361 
    362     return document && document->isMediaDocument();
    363 }
    364 
    365 PlatformMedia MediaPlayer::platformMedia() const
    366 {
    367     return m_private->platformMedia();
    368 }
    369 
    370 MediaPlayer::NetworkState MediaPlayer::networkState()
    371 {
    372     return m_private->networkState();
    373 }
    374 
    375 MediaPlayer::ReadyState MediaPlayer::readyState()
    376 {
    377     return m_private->readyState();
    378 }
    379 
    380 float MediaPlayer::volume() const
    381 {
    382     return m_volume;
    383 }
    384 
    385 void MediaPlayer::setVolume(float volume)
    386 {
    387     m_volume = volume;
    388     m_private->setVolume(volume);
    389 }
    390 
    391 bool MediaPlayer::muted() const
    392 {
    393     return m_muted;
    394 }
    395 
    396 bool MediaPlayer::supportsMuting() const
    397 {
    398     return m_private->supportsMuting();
    399 }
    400 
    401 void MediaPlayer::setMuted(bool muted)
    402 {
    403     m_muted = muted;
    404     m_private->setMuted(muted);
    405 }
    406 
    407 bool MediaPlayer::hasClosedCaptions() const
    408 {
    409     return m_private->hasClosedCaptions();
    410 }
    411 
    412 void MediaPlayer::setClosedCaptionsVisible(bool closedCaptionsVisible)
    413 {
    414     m_private->setClosedCaptionsVisible(closedCaptionsVisible);
    415 }
    416 
    417 float MediaPlayer::rate() const
    418 {
    419     return m_rate;
    420 }
    421 
    422 void MediaPlayer::setRate(float rate)
    423 {
    424     m_rate = rate;
    425     m_private->setRate(rate);
    426 }
    427 
    428 bool MediaPlayer::preservesPitch() const
    429 {
    430     return m_preservesPitch;
    431 }
    432 
    433 void MediaPlayer::setPreservesPitch(bool preservesPitch)
    434 {
    435     m_preservesPitch = preservesPitch;
    436     m_private->setPreservesPitch(preservesPitch);
    437 }
    438 
    439 PassRefPtr<TimeRanges> MediaPlayer::buffered()
    440 {
    441     return m_private->buffered();
    442 }
    443 
    444 float MediaPlayer::maxTimeSeekable()
    445 {
    446     return m_private->maxTimeSeekable();
    447 }
    448 
    449 unsigned MediaPlayer::bytesLoaded()
    450 {
    451     return m_private->bytesLoaded();
    452 }
    453 
    454 void MediaPlayer::setSize(const IntSize& size)
    455 {
    456     m_size = size;
    457     m_private->setSize(size);
    458 }
    459 
    460 bool MediaPlayer::visible() const
    461 {
    462     return m_visible;
    463 }
    464 
    465 void MediaPlayer::setVisible(bool b)
    466 {
    467     m_visible = b;
    468     m_private->setVisible(b);
    469 }
    470 
    471 bool MediaPlayer::autobuffer() const
    472 {
    473     return m_autobuffer;
    474 }
    475 
    476 void MediaPlayer::setAutobuffer(bool b)
    477 {
    478     if (m_autobuffer != b) {
    479         m_autobuffer = b;
    480         m_private->setAutobuffer(b);
    481     }
    482 }
    483 
    484 void MediaPlayer::paint(GraphicsContext* p, const IntRect& r)
    485 {
    486     m_private->paint(p, r);
    487 }
    488 
    489 void MediaPlayer::paintCurrentFrameInContext(GraphicsContext* p, const IntRect& r)
    490 {
    491     m_private->paintCurrentFrameInContext(p, r);
    492 }
    493 
    494 MediaPlayer::SupportsType MediaPlayer::supportsType(ContentType contentType)
    495 {
    496     String type = contentType.type();
    497     String codecs = contentType.parameter("codecs");
    498     MediaPlayerFactory* engine = chooseBestEngineForTypeAndCodecs(type, codecs);
    499 
    500     if (!engine)
    501         return IsNotSupported;
    502 
    503     return engine->supportsTypeAndCodecs(type, codecs);
    504 }
    505 
    506 void MediaPlayer::getSupportedTypes(HashSet<String>& types)
    507 {
    508     Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
    509     if (engines.isEmpty())
    510         return;
    511 
    512     unsigned count = engines.size();
    513     for (unsigned ndx = 0; ndx < count; ndx++)
    514         engines[ndx]->getSupportedTypes(types);
    515 }
    516 
    517 bool MediaPlayer::isAvailable()
    518 {
    519     return !installedMediaEngines().isEmpty();
    520 }
    521 
    522 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
    523 void MediaPlayer::deliverNotification(MediaPlayerProxyNotificationType notification)
    524 {
    525     m_private->deliverNotification(notification);
    526 }
    527 
    528 void MediaPlayer::setMediaPlayerProxy(WebMediaPlayerProxy* proxy)
    529 {
    530     m_playerProxy = proxy;
    531     m_private->setMediaPlayerProxy(proxy);
    532 }
    533 #endif
    534 
    535 #if USE(ACCELERATED_COMPOSITING)
    536 void MediaPlayer::acceleratedRenderingStateChanged()
    537 {
    538     m_private->acceleratedRenderingStateChanged();
    539 }
    540 
    541 bool MediaPlayer::supportsAcceleratedRendering() const
    542 {
    543     return m_private->supportsAcceleratedRendering();
    544 }
    545 #endif // USE(ACCELERATED_COMPOSITING)
    546 
    547 bool MediaPlayer::hasSingleSecurityOrigin() const
    548 {
    549     return m_private->hasSingleSecurityOrigin();
    550 }
    551 
    552 MediaPlayer::MovieLoadType MediaPlayer::movieLoadType() const
    553 {
    554     return m_private->movieLoadType();
    555 }
    556 
    557 // Client callbacks.
    558 void MediaPlayer::networkStateChanged()
    559 {
    560     if (m_mediaPlayerClient)
    561         m_mediaPlayerClient->mediaPlayerNetworkStateChanged(this);
    562 }
    563 
    564 void MediaPlayer::readyStateChanged()
    565 {
    566     if (m_mediaPlayerClient)
    567         m_mediaPlayerClient->mediaPlayerReadyStateChanged(this);
    568 }
    569 
    570 void MediaPlayer::volumeChanged(float newVolume)
    571 {
    572     m_volume = newVolume;
    573     if (m_mediaPlayerClient)
    574         m_mediaPlayerClient->mediaPlayerVolumeChanged(this);
    575 }
    576 
    577 void MediaPlayer::muteChanged(bool newMuted)
    578 {
    579     m_muted = newMuted;
    580     if (m_mediaPlayerClient)
    581         m_mediaPlayerClient->mediaPlayerMuteChanged(this);
    582 }
    583 
    584 void MediaPlayer::timeChanged()
    585 {
    586     if (m_mediaPlayerClient)
    587         m_mediaPlayerClient->mediaPlayerTimeChanged(this);
    588 }
    589 
    590 void MediaPlayer::sizeChanged()
    591 {
    592     if (m_mediaPlayerClient)
    593         m_mediaPlayerClient->mediaPlayerSizeChanged(this);
    594 }
    595 
    596 void MediaPlayer::repaint()
    597 {
    598     if (m_mediaPlayerClient)
    599         m_mediaPlayerClient->mediaPlayerRepaint(this);
    600 }
    601 
    602 void MediaPlayer::durationChanged()
    603 {
    604     if (m_mediaPlayerClient)
    605         m_mediaPlayerClient->mediaPlayerDurationChanged(this);
    606 }
    607 
    608 void MediaPlayer::rateChanged()
    609 {
    610     if (m_mediaPlayerClient)
    611         m_mediaPlayerClient->mediaPlayerRateChanged(this);
    612 }
    613 
    614 }
    615 
    616 #endif
    617