• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
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.
12  *
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.
24  */
25 
26 #include "config.h"
27 
28 #if ENABLE(VIDEO)
29 #include "MediaPlayer.h"
30 #include "MediaPlayerPrivate.h"
31 
32 #include "ContentType.h"
33 #include "IntRect.h"
34 #include "MIMETypeRegistry.h"
35 #include "FrameView.h"
36 #include "Frame.h"
37 #include "Document.h"
38 
39 #if PLATFORM(MAC)
40 #include "MediaPlayerPrivateQTKit.h"
41 #elif PLATFORM(WINCE)
42 #include "MediaPlayerPrivateWince.h"
43 #elif PLATFORM(WIN)
44 #include "MediaPlayerPrivateQuickTimeWin.h"
45 #elif PLATFORM(GTK)
46 #include "MediaPlayerPrivateGStreamer.h"
47 #elif PLATFORM(QT)
48 #include "MediaPlayerPrivatePhonon.h"
49 #elif PLATFORM(CHROMIUM)
50 #include "MediaPlayerPrivateChromium.h"
51 #elif PLATFORM(ANDROID)
52 #include "MediaPlayerPrivateAndroid.h"
53 #endif
54 
55 namespace WebCore {
56 
57 // a null player to make MediaPlayer logic simpler
58 
59 class NullMediaPlayerPrivate : public MediaPlayerPrivateInterface {
60 public:
NullMediaPlayerPrivate(MediaPlayer *)61     NullMediaPlayerPrivate(MediaPlayer*) { }
62 
load(const String &)63     virtual void load(const String&) { }
cancelLoad()64     virtual void cancelLoad() { }
65 
play()66     virtual void play() { }
pause()67     virtual void pause() { }
68 
supportsFullscreen() const69     virtual bool supportsFullscreen() const { return false; }
70 
naturalSize() const71     virtual IntSize naturalSize() const { return IntSize(0, 0); }
72 
hasVideo() const73     virtual bool hasVideo() const { return false; }
74 
setVisible(bool)75     virtual void setVisible(bool) { }
76 
duration() const77     virtual float duration() const { return 0; }
78 
currentTime() const79     virtual float currentTime() const { return 0; }
seek(float)80     virtual void seek(float) { }
seeking() const81     virtual bool seeking() const { return false; }
82 
setEndTime(float)83     virtual void setEndTime(float) { }
84 
setRate(float)85     virtual void setRate(float) { }
setPreservesPitch(bool)86     virtual void setPreservesPitch(bool) { }
paused() const87     virtual bool paused() const { return false; }
88 
setVolume(float)89     virtual void setVolume(float) { }
90 
networkState() const91     virtual MediaPlayer::NetworkState networkState() const { return MediaPlayer::Empty; }
readyState() const92     virtual MediaPlayer::ReadyState readyState() const { return MediaPlayer::HaveNothing; }
93 
maxTimeSeekable() const94     virtual float maxTimeSeekable() const { return 0; }
maxTimeBuffered() const95     virtual float maxTimeBuffered() const { return 0; }
96 
dataRate() const97     virtual int dataRate() const { return 0; }
98 
totalBytesKnown() const99     virtual bool totalBytesKnown() const { return false; }
totalBytes() const100     virtual unsigned totalBytes() const { return 0; }
bytesLoaded() const101     virtual unsigned bytesLoaded() const { return 0; }
102 
setSize(const IntSize &)103     virtual void setSize(const IntSize&) { }
104 
paint(GraphicsContext *,const IntRect &)105     virtual void paint(GraphicsContext*, const IntRect&) { }
106 
107 #if PLATFORM(ANDROID)
canLoadPoster() const108     virtual bool canLoadPoster() const { return false; }
setPoster(const String &)109     virtual void setPoster(const String&) { }
prepareToPlay()110     virtual void prepareToPlay() { }
111 #endif
112 
113 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
setPoster(const String &)114     virtual void setPoster(const String& /*url*/) { }
deliverNotification(MediaPlayerProxyNotificationType)115     virtual void deliverNotification(MediaPlayerProxyNotificationType) { }
setMediaPlayerProxy(WebMediaPlayerProxy *)116     virtual void setMediaPlayerProxy(WebMediaPlayerProxy*) { }
117 #endif
118 
hasSingleSecurityOrigin() const119     virtual bool hasSingleSecurityOrigin() const { return true; }
120 };
121 
createNullMediaPlayer(MediaPlayer * player)122 static MediaPlayerPrivateInterface* createNullMediaPlayer(MediaPlayer* player)
123 {
124     return new NullMediaPlayerPrivate(player);
125 }
126 
127 
128 // engine support
129 
130 struct MediaPlayerFactory {
MediaPlayerFactoryWebCore::MediaPlayerFactory131     MediaPlayerFactory(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsTypeAndCodecs)
132         : constructor(constructor)
133         , getSupportedTypes(getSupportedTypes)
134         , supportsTypeAndCodecs(supportsTypeAndCodecs)
135     {
136     }
137 
138     CreateMediaEnginePlayer constructor;
139     MediaEngineSupportedTypes getSupportedTypes;
140     MediaEngineSupportsType supportsTypeAndCodecs;
141 };
142 
143 static void addMediaEngine(CreateMediaEnginePlayer, MediaEngineSupportedTypes, MediaEngineSupportsType);
144 static MediaPlayerFactory* chooseBestEngineForTypeAndCodecs(const String& type, const String& codecs);
145 
installedMediaEngines()146 static Vector<MediaPlayerFactory*>& installedMediaEngines()
147 {
148     DEFINE_STATIC_LOCAL(Vector<MediaPlayerFactory*>, installedEngines, ());
149     static bool enginesQueried = false;
150 
151     if (!enginesQueried) {
152         enginesQueried = true;
153         MediaPlayerPrivate::registerMediaEngine(addMediaEngine);
154 
155         // register additional engines here
156     }
157 
158     return installedEngines;
159 }
160 
addMediaEngine(CreateMediaEnginePlayer constructor,MediaEngineSupportedTypes getSupportedTypes,MediaEngineSupportsType supportsType)161 static void addMediaEngine(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsType)
162 {
163     ASSERT(constructor);
164     ASSERT(getSupportedTypes);
165     ASSERT(supportsType);
166     installedMediaEngines().append(new MediaPlayerFactory(constructor, getSupportedTypes, supportsType));
167 }
168 
chooseBestEngineForTypeAndCodecs(const String & type,const String & codecs)169 static MediaPlayerFactory* chooseBestEngineForTypeAndCodecs(const String& type, const String& codecs)
170 {
171     Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
172 
173     if (engines.isEmpty())
174         return 0;
175 
176     MediaPlayerFactory* engine = 0;
177     MediaPlayer::SupportsType supported = MediaPlayer::IsNotSupported;
178 
179     unsigned count = engines.size();
180     for (unsigned ndx = 0; ndx < count; ndx++) {
181         MediaPlayer::SupportsType engineSupport = engines[ndx]->supportsTypeAndCodecs(type, codecs);
182         if (engineSupport > supported) {
183             supported = engineSupport;
184             engine = engines[ndx];
185         }
186     }
187 
188     return engine;
189 }
190 
191 // media player
192 
MediaPlayer(MediaPlayerClient * client)193 MediaPlayer::MediaPlayer(MediaPlayerClient* client)
194     : m_mediaPlayerClient(client)
195     , m_private(createNullMediaPlayer(this))
196     , m_currentMediaEngine(0)
197     , m_frameView(0)
198     , m_visible(false)
199     , m_rate(1.0f)
200     , m_volume(1.0f)
201     , m_preservesPitch(true)
202     , m_autobuffer(false)
203 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
204     , m_playerProxy(0)
205 #endif
206 {
207 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
208     Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
209     if (!engines.isEmpty()) {
210         m_currentMediaEngine = engines[0];
211         m_private.clear();
212         m_private.set(engines[0]->constructor(this));
213     }
214 #endif
215 }
216 
~MediaPlayer()217 MediaPlayer::~MediaPlayer()
218 {
219 }
220 
load(const String & url,const ContentType & contentType)221 void MediaPlayer::load(const String& url, const ContentType& contentType)
222 {
223     String type = contentType.type();
224     String codecs = contentType.parameter("codecs");
225 
226     // if we don't know the MIME type, see if the extension can help
227     if (type.isEmpty() || type == "application/octet-stream" || type == "text/plain") {
228         int pos = url.reverseFind('.');
229         if (pos >= 0) {
230             String extension = url.substring(pos + 1);
231             String mediaType = MIMETypeRegistry::getMediaMIMETypeForExtension(extension);
232             if (!mediaType.isEmpty())
233                 type = mediaType;
234         }
235     }
236 
237     MediaPlayerFactory* engine = 0;
238     if (!type.isEmpty())
239         engine = chooseBestEngineForTypeAndCodecs(type, codecs);
240 
241     // if we didn't find an engine that claims the MIME type, just use the first engine
242     if (!engine && !installedMediaEngines().isEmpty())
243         engine = installedMediaEngines()[0];
244 
245     // don't delete and recreate the player unless it comes from a different engine
246     if (engine && m_currentMediaEngine != engine) {
247         m_currentMediaEngine = engine;
248         m_private.clear();
249         m_private.set(engine->constructor(this));
250 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
251         m_private->setMediaPlayerProxy(m_playerProxy);
252 #endif
253 
254     }
255 
256     if (m_private)
257         m_private->load(url);
258     else
259         m_private.set(createNullMediaPlayer(this));
260 }
261 
262 #if PLATFORM(ANDROID)
canLoadPoster() const263 bool MediaPlayer::canLoadPoster() const
264 {
265     return m_private->canLoadPoster();
266 }
267 
prepareToPlay()268 void MediaPlayer::prepareToPlay()
269 {
270     m_private->prepareToPlay();
271 }
272 #endif
273 
274 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) || PLATFORM(ANDROID)
setPoster(const String & url)275 void MediaPlayer::setPoster(const String& url)
276 {
277     m_private->setPoster(url);
278 }
279 #endif
280 
cancelLoad()281 void MediaPlayer::cancelLoad()
282 {
283     m_private->cancelLoad();
284 }
285 
play()286 void MediaPlayer::play()
287 {
288     m_private->play();
289 }
290 
pause()291 void MediaPlayer::pause()
292 {
293     m_private->pause();
294 }
295 
duration() const296 float MediaPlayer::duration() const
297 {
298     return m_private->duration();
299 }
300 
startTime() const301 float MediaPlayer::startTime() const
302 {
303     return m_private->startTime();
304 }
305 
currentTime() const306 float MediaPlayer::currentTime() const
307 {
308     return m_private->currentTime();
309 }
310 
seek(float time)311 void MediaPlayer::seek(float time)
312 {
313     m_private->seek(time);
314 }
315 
paused() const316 bool MediaPlayer::paused() const
317 {
318     return m_private->paused();
319 }
320 
seeking() const321 bool MediaPlayer::seeking() const
322 {
323     return m_private->seeking();
324 }
325 
supportsFullscreen() const326 bool MediaPlayer::supportsFullscreen() const
327 {
328     return m_private->supportsFullscreen();
329 }
330 
supportsSave() const331 bool MediaPlayer::supportsSave() const
332 {
333     return m_private->supportsSave();
334 }
335 
naturalSize()336 IntSize MediaPlayer::naturalSize()
337 {
338     return m_private->naturalSize();
339 }
340 
hasVideo()341 bool MediaPlayer::hasVideo()
342 {
343     return m_private->hasVideo();
344 }
345 
inMediaDocument()346 bool MediaPlayer::inMediaDocument()
347 {
348     Frame* frame = m_frameView ? m_frameView->frame() : 0;
349     Document* document = frame ? frame->document() : 0;
350 
351     return document && document->isMediaDocument();
352 }
353 
networkState()354 MediaPlayer::NetworkState MediaPlayer::networkState()
355 {
356     return m_private->networkState();
357 }
358 
readyState()359 MediaPlayer::ReadyState MediaPlayer::readyState()
360 {
361     return m_private->readyState();
362 }
363 
volume() const364 float MediaPlayer::volume() const
365 {
366     return m_volume;
367 }
368 
setVolume(float volume)369 void MediaPlayer::setVolume(float volume)
370 {
371     m_volume = volume;
372     m_private->setVolume(volume);
373 }
374 
rate() const375 float MediaPlayer::rate() const
376 {
377     return m_rate;
378 }
379 
setRate(float rate)380 void MediaPlayer::setRate(float rate)
381 {
382     m_rate = rate;
383     m_private->setRate(rate);
384 }
385 
preservesPitch() const386 bool MediaPlayer::preservesPitch() const
387 {
388     return m_preservesPitch;
389 }
390 
setPreservesPitch(bool preservesPitch)391 void MediaPlayer::setPreservesPitch(bool preservesPitch)
392 {
393     m_preservesPitch = preservesPitch;
394     m_private->setPreservesPitch(preservesPitch);
395 }
396 
dataRate() const397 int MediaPlayer::dataRate() const
398 {
399     return m_private->dataRate();
400 }
401 
setEndTime(float time)402 void MediaPlayer::setEndTime(float time)
403 {
404     m_private->setEndTime(time);
405 }
406 
maxTimeBuffered()407 float MediaPlayer::maxTimeBuffered()
408 {
409     return m_private->maxTimeBuffered();
410 }
411 
maxTimeSeekable()412 float MediaPlayer::maxTimeSeekable()
413 {
414     return m_private->maxTimeSeekable();
415 }
416 
bytesLoaded()417 unsigned MediaPlayer::bytesLoaded()
418 {
419     return m_private->bytesLoaded();
420 }
421 
totalBytesKnown()422 bool MediaPlayer::totalBytesKnown()
423 {
424     return m_private->totalBytesKnown();
425 }
426 
totalBytes()427 unsigned MediaPlayer::totalBytes()
428 {
429     return m_private->totalBytes();
430 }
431 
setSize(const IntSize & size)432 void MediaPlayer::setSize(const IntSize& size)
433 {
434     m_size = size;
435     m_private->setSize(size);
436 }
437 
visible() const438 bool MediaPlayer::visible() const
439 {
440     return m_visible;
441 }
442 
setVisible(bool b)443 void MediaPlayer::setVisible(bool b)
444 {
445     m_visible = b;
446     m_private->setVisible(b);
447 }
448 
autobuffer() const449 bool MediaPlayer::autobuffer() const
450 {
451     return m_autobuffer;
452 }
453 
setAutobuffer(bool b)454 void MediaPlayer::setAutobuffer(bool b)
455 {
456     if (m_autobuffer != b) {
457         m_autobuffer = b;
458         m_private->setAutobuffer(b);
459     }
460 }
461 
paint(GraphicsContext * p,const IntRect & r)462 void MediaPlayer::paint(GraphicsContext* p, const IntRect& r)
463 {
464     m_private->paint(p, r);
465 }
466 
paintCurrentFrameInContext(GraphicsContext * p,const IntRect & r)467 void MediaPlayer::paintCurrentFrameInContext(GraphicsContext* p, const IntRect& r)
468 {
469     m_private->paintCurrentFrameInContext(p, r);
470 }
471 
supportsType(ContentType contentType)472 MediaPlayer::SupportsType MediaPlayer::supportsType(ContentType contentType)
473 {
474     String type = contentType.type();
475     String codecs = contentType.parameter("codecs");
476     MediaPlayerFactory* engine = chooseBestEngineForTypeAndCodecs(type, codecs);
477 
478     if (!engine)
479         return IsNotSupported;
480 
481     return engine->supportsTypeAndCodecs(type, codecs);
482 }
483 
getSupportedTypes(HashSet<String> & types)484 void MediaPlayer::getSupportedTypes(HashSet<String>& types)
485 {
486     Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
487     if (engines.isEmpty())
488         return;
489 
490     unsigned count = engines.size();
491     for (unsigned ndx = 0; ndx < count; ndx++)
492         engines[ndx]->getSupportedTypes(types);
493 }
494 
isAvailable()495 bool MediaPlayer::isAvailable()
496 {
497     return !installedMediaEngines().isEmpty();
498 }
499 
500 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
deliverNotification(MediaPlayerProxyNotificationType notification)501 void MediaPlayer::deliverNotification(MediaPlayerProxyNotificationType notification)
502 {
503     m_private->deliverNotification(notification);
504 }
505 
setMediaPlayerProxy(WebMediaPlayerProxy * proxy)506 void MediaPlayer::setMediaPlayerProxy(WebMediaPlayerProxy* proxy)
507 {
508     m_playerProxy = proxy;
509     m_private->setMediaPlayerProxy(proxy);
510 }
511 #endif
512 
513 #if USE(ACCELERATED_COMPOSITING)
acceleratedRenderingStateChanged()514 void MediaPlayer::acceleratedRenderingStateChanged()
515 {
516     m_private->acceleratedRenderingStateChanged();
517 }
518 
supportsAcceleratedRendering() const519 bool MediaPlayer::supportsAcceleratedRendering() const
520 {
521     return m_private->supportsAcceleratedRendering();
522 }
523 #endif // USE(ACCELERATED_COMPOSITING)
524 
hasSingleSecurityOrigin() const525 bool MediaPlayer::hasSingleSecurityOrigin() const
526 {
527     return m_private->hasSingleSecurityOrigin();
528 }
529 
movieLoadType() const530 MediaPlayer::MovieLoadType MediaPlayer::movieLoadType() const
531 {
532     return m_private->movieLoadType();
533 }
534 
535 // Client callbacks.
networkStateChanged()536 void MediaPlayer::networkStateChanged()
537 {
538     if (m_mediaPlayerClient)
539         m_mediaPlayerClient->mediaPlayerNetworkStateChanged(this);
540 }
541 
readyStateChanged()542 void MediaPlayer::readyStateChanged()
543 {
544     if (m_mediaPlayerClient)
545         m_mediaPlayerClient->mediaPlayerReadyStateChanged(this);
546 }
547 
volumeChanged()548 void MediaPlayer::volumeChanged()
549 {
550     if (m_mediaPlayerClient)
551         m_mediaPlayerClient->mediaPlayerVolumeChanged(this);
552 }
553 
timeChanged()554 void MediaPlayer::timeChanged()
555 {
556     if (m_mediaPlayerClient)
557         m_mediaPlayerClient->mediaPlayerTimeChanged(this);
558 }
559 
sizeChanged()560 void MediaPlayer::sizeChanged()
561 {
562     if (m_mediaPlayerClient)
563         m_mediaPlayerClient->mediaPlayerSizeChanged(this);
564 }
565 
repaint()566 void MediaPlayer::repaint()
567 {
568     if (m_mediaPlayerClient)
569         m_mediaPlayerClient->mediaPlayerRepaint(this);
570 }
571 
durationChanged()572 void MediaPlayer::durationChanged()
573 {
574     if (m_mediaPlayerClient)
575         m_mediaPlayerClient->mediaPlayerDurationChanged(this);
576 }
577 
rateChanged()578 void MediaPlayer::rateChanged()
579 {
580     if (m_mediaPlayerClient)
581         m_mediaPlayerClient->mediaPlayerRateChanged(this);
582 }
583 
584 }
585 
586 #endif
587