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