diff options
author | Feng Qian <> | 2009-04-10 18:11:29 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-04-10 18:11:29 -0700 |
commit | 8f72e70a9fd78eec56623b3a62e68f16b7b27e28 (patch) | |
tree | 181bf9a400c30a1bf34ea6d72560e8d00111d549 /WebCore/platform/graphics/MediaPlayer.cpp | |
parent | 7ed56f225e0ade046e1c2178977f72b2d896f196 (diff) | |
download | external_webkit-8f72e70a9fd78eec56623b3a62e68f16b7b27e28.zip external_webkit-8f72e70a9fd78eec56623b3a62e68f16b7b27e28.tar.gz external_webkit-8f72e70a9fd78eec56623b3a62e68f16b7b27e28.tar.bz2 |
AI 145796: Land the WebKit merge @r42026.
Automated import of CL 145796
Diffstat (limited to 'WebCore/platform/graphics/MediaPlayer.cpp')
-rw-r--r-- | WebCore/platform/graphics/MediaPlayer.cpp | 254 |
1 files changed, 231 insertions, 23 deletions
diff --git a/WebCore/platform/graphics/MediaPlayer.cpp b/WebCore/platform/graphics/MediaPlayer.cpp index 21e31fc..99d6aa4 100644 --- a/WebCore/platform/graphics/MediaPlayer.cpp +++ b/WebCore/platform/graphics/MediaPlayer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,7 +27,9 @@ #if ENABLE(VIDEO) #include "MediaPlayer.h" +#include "MediaPlayerPrivate.h" +#include "ContentType.h" #include "IntRect.h" #include "MIMETypeRegistry.h" #include "FrameView.h" @@ -47,26 +49,196 @@ #endif namespace WebCore { + +// a null player to make MediaPlayer logic simpler + +class NullMediaPlayerPrivate : public MediaPlayerPrivateInterface { +public: + NullMediaPlayerPrivate(MediaPlayer*) { } + + virtual void load(const String&) { } + virtual void cancelLoad() { } + + virtual void play() { } + virtual void pause() { } + + virtual IntSize naturalSize() const { return IntSize(0, 0); } + + virtual bool hasVideo() const { return false; } + + virtual void setVisible(bool) { } + + virtual float duration() const { return 0; } + + virtual float currentTime() const { return 0; } + virtual void seek(float) { } + virtual bool seeking() const { return false; } + + virtual void setEndTime(float) { } + + virtual void setRate(float) { } + virtual bool paused() const { return false; } + + virtual void setVolume(float) { } + + virtual MediaPlayer::NetworkState networkState() const { return MediaPlayer::Empty; } + virtual MediaPlayer::ReadyState readyState() const { return MediaPlayer::HaveNothing; } + + virtual float maxTimeSeekable() const { return 0; } + virtual float maxTimeBuffered() const { return 0; } + + virtual int dataRate() const { return 0; } + + virtual bool totalBytesKnown() const { return false; } + virtual unsigned totalBytes() const { return 0; } + virtual unsigned bytesLoaded() const { return 0; } + + virtual void setSize(const IntSize&) { } + + virtual void paint(GraphicsContext*, const IntRect&) { } + +#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) + virtual void setPoster(const String& /*url*/) { } + virtual void deliverNotification(MediaPlayerProxyNotificationType) { } + virtual void setMediaPlayerProxy(WebMediaPlayerProxy*) { } +#endif +}; + +static MediaPlayerPrivateInterface* createNullMediaPlayer(MediaPlayer* player) +{ + return new NullMediaPlayerPrivate(player); +} + + +// engine support + +struct MediaPlayerFactory { + MediaPlayerFactory(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsTypeAndCodecs) + : constructor(constructor) + , getSupportedTypes(getSupportedTypes) + , supportsTypeAndCodecs(supportsTypeAndCodecs) + { + } + + CreateMediaEnginePlayer constructor; + MediaEngineSupportedTypes getSupportedTypes; + MediaEngineSupportsType supportsTypeAndCodecs; +}; + +static void addMediaEngine(CreateMediaEnginePlayer, MediaEngineSupportedTypes, MediaEngineSupportsType); +static MediaPlayerFactory* chooseBestEngineForTypeAndCodecs(const String& type, const String& codecs); + +static Vector<MediaPlayerFactory*>& installedMediaEngines() +{ + DEFINE_STATIC_LOCAL(Vector<MediaPlayerFactory*>, installedEngines, ()); + static bool enginesQueried = false; + + if (!enginesQueried) { + enginesQueried = true; + MediaPlayerPrivate::registerMediaEngine(addMediaEngine); + + // register additional engines here + } - MediaPlayer::MediaPlayer(MediaPlayerClient* client) + return installedEngines; +} + +static void addMediaEngine(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsType) +{ + ASSERT(constructor); + ASSERT(getSupportedTypes); + ASSERT(supportsType); + installedMediaEngines().append(new MediaPlayerFactory(constructor, getSupportedTypes, supportsType)); +} + +static MediaPlayerFactory* chooseBestEngineForTypeAndCodecs(const String& type, const String& codecs) +{ + Vector<MediaPlayerFactory*>& engines = installedMediaEngines(); + + if (engines.isEmpty()) + return 0; + + MediaPlayerFactory* engine = 0; + MediaPlayer::SupportsType supported = MediaPlayer::IsNotSupported; + + unsigned count = engines.size(); + for (unsigned ndx = 0; ndx < count; ndx++) { + MediaPlayer::SupportsType engineSupport = engines[ndx]->supportsTypeAndCodecs(type, codecs); + if (engineSupport > supported) { + supported = engineSupport; + engine = engines[ndx]; + } + } + + return engine; +} + +// media player + +MediaPlayer::MediaPlayer(MediaPlayerClient* client) : m_mediaPlayerClient(client) - , m_private(new MediaPlayerPrivate(this)) + , m_private(createNullMediaPlayer(this)) + , m_currentMediaEngine(0) , m_frameView(0) , m_visible(false) , m_rate(1.0f) , m_volume(1.0f) +#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) + , m_playerProxy(0) +#endif { +#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) + Vector<MediaPlayerFactory*>& engines = installedMediaEngines(); + if (!engines.isEmpty()) { + m_currentMediaEngine = engines[0]; + m_private.clear(); + m_private.set(engines[0]->constructor(this)); + } +#endif } MediaPlayer::~MediaPlayer() { - delete m_private; } -void MediaPlayer::load(const String& url) +void MediaPlayer::load(const String& url, const ContentType& contentType) +{ + String type = contentType.type(); + String codecs = contentType.parameter("codecs"); + + // if we don't know the MIME type, see if the path can help + if (type.isEmpty()) + type = MIMETypeRegistry::getMIMETypeForPath(url); + + MediaPlayerFactory* engine = chooseBestEngineForTypeAndCodecs(type, codecs); + + // if we didn't find an engine that claims the MIME type, just use the first engine + if (!engine) + engine = installedMediaEngines()[0]; + + // don't delete and recreate the player unless it comes from a different engine + if (engine && m_currentMediaEngine != engine) { + m_currentMediaEngine = engine; + m_private.clear(); + m_private.set(engine->constructor(this)); +#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) + m_private->setMediaPlayerProxy(m_playerProxy); +#endif + + } + + if (m_private) + m_private->load(url); + else + m_private.set(createNullMediaPlayer(this)); +} + +#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) +void MediaPlayer::setPoster(const String& url) { - m_private->load(url); + m_private->setPoster(url); } +#endif void MediaPlayer::cancelLoad() { @@ -90,7 +262,7 @@ float MediaPlayer::duration() const float MediaPlayer::currentTime() const { - return m_private->currentTime(); + return m_private->currentTime(); } void MediaPlayer::seek(float time) @@ -193,10 +365,10 @@ unsigned MediaPlayer::totalBytes() return m_private->totalBytes(); } -void MediaPlayer::setRect(const IntRect& r) +void MediaPlayer::setSize(const IntSize& size) { - m_rect = r; - m_private->setRect(r); + m_size = size; + m_private->setSize(size); } bool MediaPlayer::visible() const @@ -215,29 +387,47 @@ void MediaPlayer::paint(GraphicsContext* p, const IntRect& r) m_private->paint(p, r); } -bool MediaPlayer::supportsType(const String& type) +MediaPlayer::SupportsType MediaPlayer::supportsType(ContentType contentType) { - HashSet<String> types; - getSupportedTypes(types); - return MIMETypeRegistry::isSupportedMediaMIMEType(type) && types.contains(type); + String type = contentType.type(); + String codecs = contentType.parameter("codecs"); + MediaPlayerFactory* engine = chooseBestEngineForTypeAndCodecs(type, codecs); + + if (!engine) + return IsNotSupported; + + return engine->supportsTypeAndCodecs(type, codecs); } void MediaPlayer::getSupportedTypes(HashSet<String>& types) { - MediaPlayerPrivate::getSupportedTypes(types); + Vector<MediaPlayerFactory*>& engines = installedMediaEngines(); + if (engines.isEmpty()) + return; + + unsigned count = engines.size(); + for (unsigned ndx = 0; ndx < count; ndx++) + engines[ndx]->getSupportedTypes(types); } - + bool MediaPlayer::isAvailable() { - static bool availabityKnown = false; - static bool isAvailable; - if (!availabityKnown) { - isAvailable = MediaPlayerPrivate::isAvailable(); - availabityKnown = true; - } - return isAvailable; + return !installedMediaEngines().isEmpty(); } +#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) +void MediaPlayer::deliverNotification(MediaPlayerProxyNotificationType notification) +{ + m_private->deliverNotification(notification); +} + +void MediaPlayer::setMediaPlayerProxy(WebMediaPlayerProxy* proxy) +{ + m_playerProxy = proxy; + m_private->setMediaPlayerProxy(proxy); +} +#endif + void MediaPlayer::networkStateChanged() { if (m_mediaPlayerClient) @@ -262,11 +452,29 @@ void MediaPlayer::timeChanged() m_mediaPlayerClient->mediaPlayerTimeChanged(this); } +void MediaPlayer::sizeChanged() +{ + if (m_mediaPlayerClient) + m_mediaPlayerClient->mediaPlayerSizeChanged(this); +} + void MediaPlayer::repaint() { if (m_mediaPlayerClient) m_mediaPlayerClient->mediaPlayerRepaint(this); } +void MediaPlayer::durationChanged() +{ + if (m_mediaPlayerClient) + m_mediaPlayerClient->mediaPlayerDurationChanged(this); +} + +void MediaPlayer::rateChanged() +{ + if (m_mediaPlayerClient) + m_mediaPlayerClient->mediaPlayerRateChanged(this); +} + } #endif |