summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics/MediaPlayer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform/graphics/MediaPlayer.cpp')
-rw-r--r--WebCore/platform/graphics/MediaPlayer.cpp104
1 files changed, 82 insertions, 22 deletions
diff --git a/WebCore/platform/graphics/MediaPlayer.cpp b/WebCore/platform/graphics/MediaPlayer.cpp
index dc743bf..4a39e9e 100644
--- a/WebCore/platform/graphics/MediaPlayer.cpp
+++ b/WebCore/platform/graphics/MediaPlayer.cpp
@@ -164,7 +164,8 @@ struct MediaPlayerFactory : Noncopyable {
};
static void addMediaEngine(CreateMediaEnginePlayer, MediaEngineSupportedTypes, MediaEngineSupportsType);
-static MediaPlayerFactory* chooseBestEngineForTypeAndCodecs(const String& type, const String& codecs);
+static MediaPlayerFactory* bestMediaEngineForTypeAndCodecs(const String& type, const String& codecs, MediaPlayerFactory* current = 0);
+static MediaPlayerFactory* nextMediaEngine(MediaPlayerFactory* current);
static Vector<MediaPlayerFactory*>& installedMediaEngines()
{
@@ -212,10 +213,12 @@ static const AtomicString& codecs()
return codecs;
}
-static MediaPlayerFactory* chooseBestEngineForTypeAndCodecs(const String& type, const String& codecs)
+static MediaPlayerFactory* bestMediaEngineForTypeAndCodecs(const String& type, const String& codecs, MediaPlayerFactory* current)
{
- Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
+ if (type.isEmpty())
+ return 0;
+ Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
if (engines.isEmpty())
return 0;
@@ -229,9 +232,13 @@ static MediaPlayerFactory* chooseBestEngineForTypeAndCodecs(const String& type,
MediaPlayerFactory* engine = 0;
MediaPlayer::SupportsType supported = MediaPlayer::IsNotSupported;
-
unsigned count = engines.size();
for (unsigned ndx = 0; ndx < count; ndx++) {
+ if (current) {
+ if (current == engines[ndx])
+ current = 0;
+ continue;
+ }
MediaPlayer::SupportsType engineSupport = engines[ndx]->supportsTypeAndCodecs(type, codecs);
if (engineSupport > supported) {
supported = engineSupport;
@@ -242,10 +249,27 @@ static MediaPlayerFactory* chooseBestEngineForTypeAndCodecs(const String& type,
return engine;
}
+static MediaPlayerFactory* nextMediaEngine(MediaPlayerFactory* current)
+{
+ Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
+ if (engines.isEmpty())
+ return 0;
+
+ if (!current)
+ return engines.first();
+
+ size_t currentIndex = engines.find(current);
+ if (currentIndex == WTF::notFound || currentIndex == engines.size())
+ return 0;
+
+ return engines[currentIndex + 1];
+}
+
// media player
MediaPlayer::MediaPlayer(MediaPlayerClient* client)
: m_mediaPlayerClient(client)
+ , m_reloadTimer(this, &MediaPlayer::reloadTimerFired)
, m_private(createNullMediaPlayer(this))
, m_currentMediaEngine(0)
, m_frameView(0)
@@ -268,12 +292,15 @@ MediaPlayer::MediaPlayer(MediaPlayerClient* client)
m_currentMediaEngine = engines[0];
m_private.clear();
m_private.set(engines[0]->constructor(this));
+ if (m_mediaPlayerClient)
+ m_mediaPlayerClient->mediaPlayerEngineUpdated(this);
}
#endif
}
MediaPlayer::~MediaPlayer()
{
+ m_mediaPlayerClient = 0;
}
void MediaPlayer::load(const String& url, const ContentType& contentType)
@@ -281,26 +308,38 @@ void MediaPlayer::load(const String& url, const ContentType& contentType)
String type = contentType.type().lower();
String typeCodecs = contentType.parameter(codecs());
- // If the MIME type is unhelpful, see if the type registry has a match for the file extension.
+ // If the MIME type is missing or is not meaningful, try to figure it out from the URL.
if (type.isEmpty() || type == applicationOctetStream() || type == textPlain()) {
- size_t pos = url.reverseFind('.');
- if (pos != notFound) {
- String extension = url.substring(pos + 1);
- String mediaType = MIMETypeRegistry::getMediaMIMETypeForExtension(extension);
- if (!mediaType.isEmpty())
- type = mediaType;
+ if (protocolIs(url, "data"))
+ type = mimeTypeFromDataURL(url);
+ else {
+ size_t pos = url.reverseFind('.');
+ if (pos != notFound) {
+ String extension = url.substring(pos + 1);
+ String mediaType = MIMETypeRegistry::getMediaMIMETypeForExtension(extension);
+ if (!mediaType.isEmpty())
+ type = mediaType;
+ }
}
}
- MediaPlayerFactory* engine = 0;
- if (!type.isEmpty())
- engine = chooseBestEngineForTypeAndCodecs(type, typeCodecs);
+ m_url = url;
+ m_contentMIMEType = type;
+ m_contentTypeCodecs = typeCodecs;
+ loadWithNextMediaEngine(0);
+}
- // If we didn't find an engine and no MIME type is specified, just use the first engine.
- if (!engine && type.isEmpty() && !installedMediaEngines().isEmpty())
- engine = installedMediaEngines()[0];
+void MediaPlayer::loadWithNextMediaEngine(MediaPlayerFactory* current)
+{
+ MediaPlayerFactory* engine;
+
+ // If no MIME type is specified, just use the next engine.
+ if (m_contentMIMEType.isEmpty())
+ engine = nextMediaEngine(current);
+ else
+ engine = bestMediaEngineForTypeAndCodecs(m_contentMIMEType, m_contentTypeCodecs, current);
- // Don't delete and recreate the player unless it comes from a different engine
+ // Don't delete and recreate the player unless it comes from a different engine.
if (!engine) {
m_currentMediaEngine = engine;
m_private.clear();
@@ -308,6 +347,8 @@ void MediaPlayer::load(const String& url, const ContentType& contentType)
m_currentMediaEngine = engine;
m_private.clear();
m_private.set(engine->constructor(this));
+ if (m_mediaPlayerClient)
+ m_mediaPlayerClient->mediaPlayerEngineUpdated(this);
#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
m_private->setMediaPlayerProxy(m_playerProxy);
#endif
@@ -316,9 +357,12 @@ void MediaPlayer::load(const String& url, const ContentType& contentType)
}
if (m_private)
- m_private->load(url);
- else
+ m_private->load(m_url);
+ else {
m_private.set(createNullMediaPlayer(this));
+ if (m_mediaPlayerClient)
+ m_mediaPlayerClient->mediaPlayerEngineUpdated(this);
+ }
}
bool MediaPlayer::hasAvailableVideoFrame() const
@@ -559,7 +603,7 @@ void MediaPlayer::paintCurrentFrameInContext(GraphicsContext* p, const IntRect&
m_private->paintCurrentFrameInContext(p, r);
}
-MediaPlayer::SupportsType MediaPlayer::supportsType(ContentType contentType)
+MediaPlayer::SupportsType MediaPlayer::supportsType(const ContentType& contentType)
{
String type = contentType.type().lower();
String typeCodecs = contentType.parameter(codecs());
@@ -569,7 +613,7 @@ MediaPlayer::SupportsType MediaPlayer::supportsType(ContentType contentType)
if (type == applicationOctetStream())
return IsNotSupported;
- MediaPlayerFactory* engine = chooseBestEngineForTypeAndCodecs(type, typeCodecs);
+ MediaPlayerFactory* engine = bestMediaEngineForTypeAndCodecs(type, typeCodecs);
if (!engine)
return IsNotSupported;
@@ -652,9 +696,25 @@ double MediaPlayer::maximumDurationToCacheMediaTime() const
return m_private->maximumDurationToCacheMediaTime();
}
+void MediaPlayer::reloadTimerFired(Timer<MediaPlayer>*)
+{
+ m_private->cancelLoad();
+ loadWithNextMediaEngine(m_currentMediaEngine);
+}
+
+
// Client callbacks.
void MediaPlayer::networkStateChanged()
{
+ // If more than one media engine is installed and this one failed before finding metadata,
+ // let the next engine try.
+ if (m_private->networkState() >= FormatError
+ && m_private->readyState() < HaveMetadata
+ && installedMediaEngines().size() > 1
+ && bestMediaEngineForTypeAndCodecs(m_contentMIMEType, m_contentTypeCodecs, m_currentMediaEngine)) {
+ m_reloadTimer.startOneShot(0);
+ return;
+ }
if (m_mediaPlayerClient)
m_mediaPlayerClient->mediaPlayerNetworkStateChanged(this);
}