summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics/MediaPlayer.cpp
diff options
context:
space:
mode:
authorFeng Qian <>2009-04-10 18:11:29 -0700
committerThe Android Open Source Project <initial-contribution@android.com>2009-04-10 18:11:29 -0700
commit8f72e70a9fd78eec56623b3a62e68f16b7b27e28 (patch)
tree181bf9a400c30a1bf34ea6d72560e8d00111d549 /WebCore/platform/graphics/MediaPlayer.cpp
parent7ed56f225e0ade046e1c2178977f72b2d896f196 (diff)
downloadexternal_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.cpp254
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