2 * Copyright (C) 2007, 2008, 2009, 2010 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"
31 #include "ContentType.h"
34 #include "FrameView.h"
36 #include "MIMETypeRegistry.h"
37 #include "MediaPlayerPrivate.h"
38 #include "TimeRanges.h"
45 #include "MediaPlayerPrivateGStreamer.h"
49 #include "MediaPlayerPrivateQTKit.h"
50 #elif OS(WINCE) && !PLATFORM(QT)
51 #include "MediaPlayerPrivateWinCE.h"
53 #include "MediaPlayerPrivateQuickTimeVisualContext.h"
54 #include "MediaPlayerPrivateQuicktimeWin.h"
56 #if USE(QT_MULTIMEDIA)
57 #include "MediaPlayerPrivateQt.h"
59 #include "MediaPlayerPrivatePhonon.h"
61 #elif PLATFORM(CHROMIUM)
62 #include "MediaPlayerPrivateChromium.h"
63 #elif PLATFORM(ANDROID)
64 #include "MediaPlayerPrivateAndroid.h"
69 const PlatformMedia NoPlatformMedia = { PlatformMedia::None, {0} };
71 // a null player to make MediaPlayer logic simpler
73 class NullMediaPlayerPrivate : public MediaPlayerPrivateInterface {
75 NullMediaPlayerPrivate(MediaPlayer*) { }
77 virtual void load(const String&) { }
78 virtual void cancelLoad() { }
80 virtual void prepareToPlay() { }
81 virtual void play() { }
82 virtual void pause() { }
84 virtual PlatformMedia platformMedia() const { return NoPlatformMedia; }
85 #if USE(ACCELERATED_COMPOSITING)
86 virtual PlatformLayer* platformLayer() const { return 0; }
89 virtual IntSize naturalSize() const { return IntSize(0, 0); }
91 virtual bool hasVideo() const { return false; }
92 virtual bool hasAudio() const { return false; }
94 virtual void setVisible(bool) { }
96 virtual float duration() const { return 0; }
98 virtual float currentTime() const { return 0; }
99 virtual void seek(float) { }
100 virtual bool seeking() const { return false; }
102 virtual void setRate(float) { }
103 virtual void setPreservesPitch(bool) { }
104 virtual bool paused() const { return false; }
106 virtual void setVolume(float) { }
108 virtual bool supportsMuting() const { return false; }
109 virtual void setMuted(bool) { }
111 virtual bool hasClosedCaptions() const { return false; }
112 virtual void setClosedCaptionsVisible(bool) { };
114 virtual MediaPlayer::NetworkState networkState() const { return MediaPlayer::Empty; }
115 virtual MediaPlayer::ReadyState readyState() const { return MediaPlayer::HaveNothing; }
117 virtual float maxTimeSeekable() const { return 0; }
118 virtual PassRefPtr<TimeRanges> buffered() const { return TimeRanges::create(); }
120 virtual unsigned totalBytes() const { return 0; }
121 virtual unsigned bytesLoaded() const { return 0; }
123 virtual void setSize(const IntSize&) { }
125 virtual void paint(GraphicsContext*, const IntRect&) { }
127 virtual bool canLoadPoster() const { return false; }
128 virtual void setPoster(const String&) { }
130 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
131 virtual void deliverNotification(MediaPlayerProxyNotificationType) { }
132 virtual void setMediaPlayerProxy(WebMediaPlayerProxy*) { }
133 virtual void setControls(bool) { }
136 virtual bool hasSingleSecurityOrigin() const { return true; }
139 static MediaPlayerPrivateInterface* createNullMediaPlayer(MediaPlayer* player)
141 return new NullMediaPlayerPrivate(player);
147 struct MediaPlayerFactory : Noncopyable {
148 MediaPlayerFactory(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsTypeAndCodecs)
149 : constructor(constructor)
150 , getSupportedTypes(getSupportedTypes)
151 , supportsTypeAndCodecs(supportsTypeAndCodecs)
155 CreateMediaEnginePlayer constructor;
156 MediaEngineSupportedTypes getSupportedTypes;
157 MediaEngineSupportsType supportsTypeAndCodecs;
160 static void addMediaEngine(CreateMediaEnginePlayer, MediaEngineSupportedTypes, MediaEngineSupportsType);
161 static MediaPlayerFactory* chooseBestEngineForTypeAndCodecs(const String& type, const String& codecs);
163 static Vector<MediaPlayerFactory*>& installedMediaEngines()
165 DEFINE_STATIC_LOCAL(Vector<MediaPlayerFactory*>, installedEngines, ());
166 static bool enginesQueried = false;
168 if (!enginesQueried) {
169 enginesQueried = true;
171 MediaPlayerPrivateGStreamer::registerMediaEngine(addMediaEngine);
175 MediaPlayerPrivateQuickTimeVisualContext::registerMediaEngine(addMediaEngine);
177 #if USE(QT_MULTIMEDIA)
178 MediaPlayerPrivateQt::registerMediaEngine(addMediaEngine);
180 MediaPlayerPrivatePhonon::registerMediaEngine(addMediaEngine);
182 #elif !PLATFORM(GTK) && !PLATFORM(EFL)
183 // FIXME: currently all the MediaEngines are named
184 // MediaPlayerPrivate. This code will need an update when bug
185 // 36663 is adressed.
186 MediaPlayerPrivate::registerMediaEngine(addMediaEngine);
189 // register additional engines here
192 return installedEngines;
195 static void addMediaEngine(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsType)
198 ASSERT(getSupportedTypes);
199 ASSERT(supportsType);
200 installedMediaEngines().append(new MediaPlayerFactory(constructor, getSupportedTypes, supportsType));
203 static const AtomicString& applicationOctetStream()
205 DEFINE_STATIC_LOCAL(const AtomicString, applicationOctetStream, ("application/octet-stream"));
206 return applicationOctetStream;
209 static const AtomicString& textPlain()
211 DEFINE_STATIC_LOCAL(const AtomicString, textPlain, ("text/plain"));
215 static const AtomicString& codecs()
217 DEFINE_STATIC_LOCAL(const AtomicString, codecs, ("codecs"));
221 static MediaPlayerFactory* chooseBestEngineForTypeAndCodecs(const String& type, const String& codecs)
223 Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
225 if (engines.isEmpty())
228 // 4.8.10.3 MIME types - In the absence of a specification to the contrary, the MIME type "application/octet-stream"
229 // when used with parameters, e.g. "application/octet-stream;codecs=theora", is a type that the user agent knows
231 if (type == applicationOctetStream()) {
232 if (!codecs.isEmpty())
236 MediaPlayerFactory* engine = 0;
237 MediaPlayer::SupportsType supported = MediaPlayer::IsNotSupported;
239 unsigned count = engines.size();
240 for (unsigned ndx = 0; ndx < count; ndx++) {
241 MediaPlayer::SupportsType engineSupport = engines[ndx]->supportsTypeAndCodecs(type, codecs);
242 if (engineSupport > supported) {
243 supported = engineSupport;
244 engine = engines[ndx];
253 MediaPlayer::MediaPlayer(MediaPlayerClient* client)
254 : m_mediaPlayerClient(client)
255 , m_private(createNullMediaPlayer(this))
256 , m_currentMediaEngine(0)
263 , m_preservesPitch(true)
264 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
267 #if PLATFORM(ANDROID)
268 , m_mediaElementType(Video)
271 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
272 Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
273 if (!engines.isEmpty()) {
274 m_currentMediaEngine = engines[0];
276 m_private.set(engines[0]->constructor(this));
281 MediaPlayer::~MediaPlayer()
285 void MediaPlayer::load(const String& url, const ContentType& contentType)
287 String type = contentType.type().lower();
288 String typeCodecs = contentType.parameter(codecs());
290 // If the MIME type is unhelpful, see if the type registry has a match for the file extension.
291 if (type.isEmpty() || type == applicationOctetStream() || type == textPlain()) {
292 size_t pos = url.reverseFind('.');
293 if (pos != notFound) {
294 String extension = url.substring(pos + 1);
295 String mediaType = MIMETypeRegistry::getMediaMIMETypeForExtension(extension);
296 if (!mediaType.isEmpty())
301 MediaPlayerFactory* engine = 0;
303 engine = chooseBestEngineForTypeAndCodecs(type, typeCodecs);
305 // If we didn't find an engine and no MIME type is specified, just use the first engine.
306 if (!engine && type.isEmpty() && !installedMediaEngines().isEmpty())
307 engine = installedMediaEngines()[0];
309 // Don't delete and recreate the player unless it comes from a different engine
311 m_currentMediaEngine = engine;
313 } else if (m_currentMediaEngine != engine) {
314 m_currentMediaEngine = engine;
316 m_private.set(engine->constructor(this));
317 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
318 m_private->setMediaPlayerProxy(m_playerProxy);
320 m_private->setPreload(m_preload);
321 m_private->setPreservesPitch(preservesPitch());
325 m_private->load(url);
327 m_private.set(createNullMediaPlayer(this));
330 bool MediaPlayer::hasAvailableVideoFrame() const
332 return m_private->hasAvailableVideoFrame();
335 void MediaPlayer::prepareForRendering()
337 return m_private->prepareForRendering();
340 bool MediaPlayer::canLoadPoster() const
342 return m_private->canLoadPoster();
345 void MediaPlayer::setPoster(const String& url)
347 m_private->setPoster(url);
350 void MediaPlayer::cancelLoad()
352 m_private->cancelLoad();
355 void MediaPlayer::prepareToPlay()
357 m_private->prepareToPlay();
360 void MediaPlayer::play()
365 void MediaPlayer::pause()
370 float MediaPlayer::duration() const
372 return m_private->duration();
375 float MediaPlayer::startTime() const
377 return m_private->startTime();
380 float MediaPlayer::currentTime() const
382 return m_private->currentTime();
385 void MediaPlayer::seek(float time)
387 m_private->seek(time);
390 bool MediaPlayer::paused() const
392 return m_private->paused();
395 bool MediaPlayer::seeking() const
397 return m_private->seeking();
400 bool MediaPlayer::supportsFullscreen() const
402 return m_private->supportsFullscreen();
405 bool MediaPlayer::supportsSave() const
407 return m_private->supportsSave();
410 IntSize MediaPlayer::naturalSize()
412 return m_private->naturalSize();
415 bool MediaPlayer::hasVideo() const
417 return m_private->hasVideo();
420 bool MediaPlayer::hasAudio() const
422 return m_private->hasAudio();
425 bool MediaPlayer::inMediaDocument()
427 Frame* frame = m_frameView ? m_frameView->frame() : 0;
428 Document* document = frame ? frame->document() : 0;
430 return document && document->isMediaDocument();
433 PlatformMedia MediaPlayer::platformMedia() const
435 return m_private->platformMedia();
438 #if USE(ACCELERATED_COMPOSITING)
439 PlatformLayer* MediaPlayer::platformLayer() const
441 return m_private->platformLayer();
445 MediaPlayer::NetworkState MediaPlayer::networkState()
447 return m_private->networkState();
450 MediaPlayer::ReadyState MediaPlayer::readyState()
452 return m_private->readyState();
455 float MediaPlayer::volume() const
460 void MediaPlayer::setVolume(float volume)
464 if (m_private->supportsMuting() || !m_muted)
465 m_private->setVolume(volume);
468 bool MediaPlayer::muted() const
473 void MediaPlayer::setMuted(bool muted)
477 if (m_private->supportsMuting())
478 m_private->setMuted(muted);
480 m_private->setVolume(muted ? 0 : m_volume);
483 bool MediaPlayer::hasClosedCaptions() const
485 return m_private->hasClosedCaptions();
488 void MediaPlayer::setClosedCaptionsVisible(bool closedCaptionsVisible)
490 m_private->setClosedCaptionsVisible(closedCaptionsVisible);
493 float MediaPlayer::rate() const
498 void MediaPlayer::setRate(float rate)
501 m_private->setRate(rate);
504 bool MediaPlayer::preservesPitch() const
506 return m_preservesPitch;
509 void MediaPlayer::setPreservesPitch(bool preservesPitch)
511 m_preservesPitch = preservesPitch;
512 m_private->setPreservesPitch(preservesPitch);
515 PassRefPtr<TimeRanges> MediaPlayer::buffered()
517 return m_private->buffered();
520 float MediaPlayer::maxTimeSeekable()
522 return m_private->maxTimeSeekable();
525 unsigned MediaPlayer::bytesLoaded()
527 return m_private->bytesLoaded();
530 void MediaPlayer::setSize(const IntSize& size)
533 m_private->setSize(size);
536 bool MediaPlayer::visible() const
541 void MediaPlayer::setVisible(bool b)
544 m_private->setVisible(b);
547 MediaPlayer::Preload MediaPlayer::preload() const
552 void MediaPlayer::setPreload(MediaPlayer::Preload preload)
555 m_private->setPreload(preload);
558 void MediaPlayer::paint(GraphicsContext* p, const IntRect& r)
560 m_private->paint(p, r);
563 void MediaPlayer::paintCurrentFrameInContext(GraphicsContext* p, const IntRect& r)
565 m_private->paintCurrentFrameInContext(p, r);
568 MediaPlayer::SupportsType MediaPlayer::supportsType(ContentType contentType)
570 String type = contentType.type().lower();
571 String typeCodecs = contentType.parameter(codecs());
573 // 4.8.10.3 MIME types - The canPlayType(type) method must return the empty string if type is a type that the
574 // user agent knows it cannot render or is the type "application/octet-stream"
575 if (type == applicationOctetStream())
576 return IsNotSupported;
578 MediaPlayerFactory* engine = chooseBestEngineForTypeAndCodecs(type, typeCodecs);
580 return IsNotSupported;
582 return engine->supportsTypeAndCodecs(type, typeCodecs);
585 void MediaPlayer::getSupportedTypes(HashSet<String>& types)
587 Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
588 if (engines.isEmpty())
591 unsigned count = engines.size();
592 for (unsigned ndx = 0; ndx < count; ndx++)
593 engines[ndx]->getSupportedTypes(types);
596 bool MediaPlayer::isAvailable()
598 return !installedMediaEngines().isEmpty();
601 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
602 void MediaPlayer::deliverNotification(MediaPlayerProxyNotificationType notification)
604 m_private->deliverNotification(notification);
607 void MediaPlayer::setMediaPlayerProxy(WebMediaPlayerProxy* proxy)
609 m_playerProxy = proxy;
610 m_private->setMediaPlayerProxy(proxy);
613 void MediaPlayer::setControls(bool controls)
615 m_private->setControls(controls);
618 void MediaPlayer::enterFullscreen()
620 m_private->enterFullscreen();
623 void MediaPlayer::exitFullscreen()
625 m_private->exitFullscreen();
629 #if USE(ACCELERATED_COMPOSITING)
630 void MediaPlayer::acceleratedRenderingStateChanged()
632 m_private->acceleratedRenderingStateChanged();
635 bool MediaPlayer::supportsAcceleratedRendering() const
637 return m_private->supportsAcceleratedRendering();
639 #endif // USE(ACCELERATED_COMPOSITING)
641 bool MediaPlayer::hasSingleSecurityOrigin() const
643 return m_private->hasSingleSecurityOrigin();
646 MediaPlayer::MovieLoadType MediaPlayer::movieLoadType() const
648 return m_private->movieLoadType();
651 float MediaPlayer::mediaTimeForTimeValue(float timeValue) const
653 return m_private->mediaTimeForTimeValue(timeValue);
657 void MediaPlayer::networkStateChanged()
659 if (m_mediaPlayerClient)
660 m_mediaPlayerClient->mediaPlayerNetworkStateChanged(this);
663 void MediaPlayer::readyStateChanged()
665 if (m_mediaPlayerClient)
666 m_mediaPlayerClient->mediaPlayerReadyStateChanged(this);
669 void MediaPlayer::volumeChanged(float newVolume)
671 m_volume = newVolume;
672 if (m_mediaPlayerClient)
673 m_mediaPlayerClient->mediaPlayerVolumeChanged(this);
676 void MediaPlayer::muteChanged(bool newMuted)
679 if (m_mediaPlayerClient)
680 m_mediaPlayerClient->mediaPlayerMuteChanged(this);
683 void MediaPlayer::timeChanged()
685 if (m_mediaPlayerClient)
686 m_mediaPlayerClient->mediaPlayerTimeChanged(this);
689 void MediaPlayer::sizeChanged()
691 if (m_mediaPlayerClient)
692 m_mediaPlayerClient->mediaPlayerSizeChanged(this);
695 void MediaPlayer::repaint()
697 if (m_mediaPlayerClient)
698 m_mediaPlayerClient->mediaPlayerRepaint(this);
701 void MediaPlayer::durationChanged()
703 if (m_mediaPlayerClient)
704 m_mediaPlayerClient->mediaPlayerDurationChanged(this);
707 void MediaPlayer::rateChanged()
709 if (m_mediaPlayerClient)
710 m_mediaPlayerClient->mediaPlayerRateChanged(this);
713 void MediaPlayer::playbackStateChanged()
715 if (m_mediaPlayerClient)
716 m_mediaPlayerClient->mediaPlayerPlaybackStateChanged(this);