2 * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
29 #include "MediaPlayer.h"
30 #include "MediaPlayerPrivate.h"
32 #include "ContentType.h"
34 #include "MIMETypeRegistry.h"
35 #include "FrameView.h"
40 #include "MediaPlayerPrivateQTKit.h"
42 #include "MediaPlayerPrivateQuickTimeWin.h"
44 #include "MediaPlayerPrivateGStreamer.h"
46 #include "MediaPlayerPrivatePhonon.h"
47 #elif PLATFORM(CHROMIUM)
48 #include "MediaPlayerPrivateChromium.h"
53 // a null player to make MediaPlayer logic simpler
55 class NullMediaPlayerPrivate : public MediaPlayerPrivateInterface {
57 NullMediaPlayerPrivate(MediaPlayer*) { }
59 virtual void load(const String&) { }
60 virtual void cancelLoad() { }
62 virtual void play() { }
63 virtual void pause() { }
65 virtual IntSize naturalSize() const { return IntSize(0, 0); }
67 virtual bool hasVideo() const { return false; }
69 virtual void setVisible(bool) { }
71 virtual float duration() const { return 0; }
73 virtual float currentTime() const { return 0; }
74 virtual void seek(float) { }
75 virtual bool seeking() const { return false; }
77 virtual void setEndTime(float) { }
79 virtual void setRate(float) { }
80 virtual bool paused() const { return false; }
82 virtual void setVolume(float) { }
84 virtual MediaPlayer::NetworkState networkState() const { return MediaPlayer::Empty; }
85 virtual MediaPlayer::ReadyState readyState() const { return MediaPlayer::DataUnavailable; }
87 virtual float maxTimeSeekable() const { return 0; }
88 virtual float maxTimeBuffered() const { return 0; }
90 virtual int dataRate() const { return 0; }
92 virtual bool totalBytesKnown() const { return false; }
93 virtual unsigned totalBytes() const { return 0; }
94 virtual unsigned bytesLoaded() const { return 0; }
96 virtual void setRect(const IntRect&) { }
98 virtual void paint(GraphicsContext*, const IntRect&) { }
101 static MediaPlayerPrivateInterface* createNullMediaPlayer(MediaPlayer* player)
103 return new NullMediaPlayerPrivate(player);
109 struct MediaPlayerFactory {
110 MediaPlayerFactory(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsTypeAndCodecs)
111 : constructor(constructor)
112 , getSupportedTypes(getSupportedTypes)
113 , supportsTypeAndCodecs(supportsTypeAndCodecs)
117 CreateMediaEnginePlayer constructor;
118 MediaEngineSupportedTypes getSupportedTypes;
119 MediaEngineSupportsType supportsTypeAndCodecs;
122 static void addMediaEngine(CreateMediaEnginePlayer, MediaEngineSupportedTypes, MediaEngineSupportsType);
123 static MediaPlayerFactory* chooseBestEngineForTypeAndCodecs(const String& type, const String& codecs);
125 static Vector<MediaPlayerFactory*>& installedMediaEngines()
127 DEFINE_STATIC_LOCAL(Vector<MediaPlayerFactory*>, installedEngines, ());
128 static bool enginesQueried = false;
130 if (!enginesQueried) {
131 enginesQueried = true;
132 MediaPlayerPrivate::registerMediaEngine(addMediaEngine);
134 // register additional engines here
137 return installedEngines;
140 static void addMediaEngine(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsType)
143 ASSERT(getSupportedTypes);
144 ASSERT(supportsType);
145 installedMediaEngines().append(new MediaPlayerFactory(constructor, getSupportedTypes, supportsType));
148 static MediaPlayerFactory* chooseBestEngineForTypeAndCodecs(const String& type, const String& codecs)
150 Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
152 if (engines.isEmpty())
155 MediaPlayerFactory* engine = 0;
156 MediaPlayer::SupportsType supported = MediaPlayer::IsNotSupported;
158 unsigned count = engines.size();
159 for (unsigned ndx = 0; ndx < count; ndx++) {
160 MediaPlayer::SupportsType engineSupport = engines[ndx]->supportsTypeAndCodecs(type, codecs);
161 if (engineSupport > supported) {
162 supported = engineSupport;
163 engine = engines[ndx];
172 MediaPlayer::MediaPlayer(MediaPlayerClient* client)
173 : m_mediaPlayerClient(client)
174 , m_private(createNullMediaPlayer(this))
175 , m_currentMediaEngine(0)
183 MediaPlayer::~MediaPlayer()
187 void MediaPlayer::load(const String& url, const String& mimeType)
189 // if we don't know the MIME type, see if the path can help
190 String type = mimeType.isEmpty() ? MIMETypeRegistry::getMIMETypeForPath(url) : mimeType;
191 String codecs = ContentType(type).parameter("codecs");
193 MediaPlayerFactory* engine = chooseBestEngineForTypeAndCodecs(type, codecs);
195 // if we didn't find an engine that claims the MIME type, just use the first engine
197 engine = installedMediaEngines()[0];
199 // don't delete and recreate the player unless it comes from a different engine
200 if (engine && m_currentMediaEngine != engine) {
201 m_currentMediaEngine = engine;
203 m_private.set(engine->constructor(this));
207 m_private->load(url);
209 m_private.set(createNullMediaPlayer(this));
212 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
213 void MediaPlayer::setPoster(const String& url)
215 m_private->setPoster(url);
219 void MediaPlayer::cancelLoad()
221 m_private->cancelLoad();
224 void MediaPlayer::play()
229 void MediaPlayer::pause()
234 float MediaPlayer::duration() const
236 return m_private->duration();
239 float MediaPlayer::currentTime() const
241 return m_private->currentTime();
244 void MediaPlayer::seek(float time)
246 m_private->seek(time);
249 bool MediaPlayer::paused() const
251 return m_private->paused();
254 bool MediaPlayer::seeking() const
256 return m_private->seeking();
259 IntSize MediaPlayer::naturalSize()
261 return m_private->naturalSize();
264 bool MediaPlayer::hasVideo()
266 return m_private->hasVideo();
269 bool MediaPlayer::inMediaDocument()
271 Frame* frame = m_frameView ? m_frameView->frame() : 0;
272 Document* document = frame ? frame->document() : 0;
274 return document && document->isMediaDocument();
277 MediaPlayer::NetworkState MediaPlayer::networkState()
279 return m_private->networkState();
282 MediaPlayer::ReadyState MediaPlayer::readyState()
284 return m_private->readyState();
287 float MediaPlayer::volume() const
292 void MediaPlayer::setVolume(float volume)
295 m_private->setVolume(volume);
298 float MediaPlayer::rate() const
303 void MediaPlayer::setRate(float rate)
306 m_private->setRate(rate);
309 int MediaPlayer::dataRate() const
311 return m_private->dataRate();
314 void MediaPlayer::setEndTime(float time)
316 m_private->setEndTime(time);
319 float MediaPlayer::maxTimeBuffered()
321 return m_private->maxTimeBuffered();
324 float MediaPlayer::maxTimeSeekable()
326 return m_private->maxTimeSeekable();
329 unsigned MediaPlayer::bytesLoaded()
331 return m_private->bytesLoaded();
334 bool MediaPlayer::totalBytesKnown()
336 return m_private->totalBytesKnown();
339 unsigned MediaPlayer::totalBytes()
341 return m_private->totalBytes();
344 void MediaPlayer::setRect(const IntRect& r)
347 m_private->setRect(r);
350 bool MediaPlayer::visible() const
355 void MediaPlayer::setVisible(bool b)
358 m_private->setVisible(b);
361 void MediaPlayer::paint(GraphicsContext* p, const IntRect& r)
363 m_private->paint(p, r);
366 MediaPlayer::SupportsType MediaPlayer::supportsType(const String& type, const String& codecs)
368 MediaPlayerFactory* engine = chooseBestEngineForTypeAndCodecs(type, codecs);
371 return IsNotSupported;
373 return engine->supportsTypeAndCodecs(type, codecs);
376 void MediaPlayer::getSupportedTypes(HashSet<String>& types)
378 Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
379 if (engines.isEmpty())
382 unsigned count = engines.size();
383 for (unsigned ndx = 0; ndx < count; ndx++)
384 engines[ndx]->getSupportedTypes(types);
387 bool MediaPlayer::isAvailable()
389 return !installedMediaEngines().isEmpty();
392 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
393 void MediaPlayer::deliverNotification(MediaPlayerProxyNotificationType notification)
395 m_private->deliverNotification(notification);
398 void MediaPlayer::setMediaPlayerProxy(WebMediaPlayerProxy* helper)
400 m_private->setMediaPlayerProxy(helper);
404 void MediaPlayer::networkStateChanged()
406 if (m_mediaPlayerClient)
407 m_mediaPlayerClient->mediaPlayerNetworkStateChanged(this);
410 void MediaPlayer::readyStateChanged()
412 if (m_mediaPlayerClient)
413 m_mediaPlayerClient->mediaPlayerReadyStateChanged(this);
416 void MediaPlayer::volumeChanged()
418 if (m_mediaPlayerClient)
419 m_mediaPlayerClient->mediaPlayerVolumeChanged(this);
422 void MediaPlayer::timeChanged()
424 if (m_mediaPlayerClient)
425 m_mediaPlayerClient->mediaPlayerTimeChanged(this);
428 void MediaPlayer::repaint()
430 if (m_mediaPlayerClient)
431 m_mediaPlayerClient->mediaPlayerRepaint(this);