eb93269c28d00eb431955647d38049f0d7ed813d
[WebKit-https.git] / WebCore / platform / graphics / MediaPlayer.cpp
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 "IntRect.h"
33 #include "MIMETypeRegistry.h"
34 #include "FrameView.h"
35 #include "Frame.h"
36 #include "Document.h"
37
38 #if PLATFORM(MAC)
39 #include "MediaPlayerPrivateQTKit.h"
40 #elif PLATFORM(WIN)
41 #include "MediaPlayerPrivateQuickTimeWin.h"
42 #elif PLATFORM(GTK)
43 #include "MediaPlayerPrivateGStreamer.h"
44 #elif PLATFORM(QT)
45 #include "MediaPlayerPrivatePhonon.h"
46 #elif PLATFORM(CHROMIUM)
47 #include "MediaPlayerPrivateChromium.h"
48 #endif
49
50 namespace WebCore {
51
52 // a null player to make MediaPlayer logic simpler
53
54 class NullMediaPlayerPrivate : public MediaPlayerPrivateInterface {
55 public:
56     NullMediaPlayerPrivate(MediaPlayer*) { }
57
58     virtual void load(const String&) { }
59     virtual void cancelLoad() { }
60     
61     virtual void play() { }
62     virtual void pause() { }    
63
64     virtual IntSize naturalSize() const { return IntSize(0, 0); }
65
66     virtual bool hasVideo() const { return false; }
67
68     virtual void setVisible(bool) { }
69
70     virtual float duration() const { return 0; }
71
72     virtual float currentTime() const { return 0; }
73     virtual void seek(float) { }
74     virtual bool seeking() const { return false; }
75
76     virtual void setEndTime(float) { }
77
78     virtual void setRate(float) { }
79     virtual bool paused() const { return false; }
80
81     virtual void setVolume(float) { }
82
83     virtual MediaPlayer::NetworkState networkState() const { return MediaPlayer::Empty; }
84     virtual MediaPlayer::ReadyState readyState() const { return MediaPlayer::DataUnavailable; }
85
86     virtual float maxTimeSeekable() const { return 0; }
87     virtual float maxTimeBuffered() const { return 0; }
88
89     virtual int dataRate() const { return 0; }
90
91     virtual bool totalBytesKnown() const { return false; }
92     virtual unsigned totalBytes() const { return 0; }
93     virtual unsigned bytesLoaded() const { return 0; }
94
95     virtual void setRect(const IntRect&) { }
96
97     virtual void paint(GraphicsContext*, const IntRect&) { }
98 };
99
100 static MediaPlayerPrivateInterface* createNullMediaPlayer(MediaPlayer* player) 
101
102     return new NullMediaPlayerPrivate(player); 
103 }
104
105
106 // engine support
107
108 struct MediaPlayerFactory {
109     MediaPlayerFactory(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsTypeAndCodecs) 
110         : constructor(constructor)
111         , getSupportedTypes(getSupportedTypes)
112         , supportsTypeAndCodecs(supportsTypeAndCodecs)  
113     { 
114     }
115
116     CreateMediaEnginePlayer constructor;
117     MediaEngineSupportedTypes getSupportedTypes;
118     MediaEngineSupportsType supportsTypeAndCodecs;
119 };
120
121 static void addMediaEngine(CreateMediaEnginePlayer, MediaEngineSupportedTypes, MediaEngineSupportsType);
122 static MediaPlayerFactory* chooseBestEngineForTypeAndCodecs(const String& type, const String& codecs);
123
124 static Vector<MediaPlayerFactory*>& installedMediaEngines() 
125 {
126     DEFINE_STATIC_LOCAL(Vector<MediaPlayerFactory*>, installedEngines, ());
127     static bool enginesQueried = false;
128
129     if (!enginesQueried) {
130         enginesQueried = true;
131         MediaPlayerPrivate::registerMediaEngine(addMediaEngine);
132
133         // register additional engines here
134     }
135     
136     return installedEngines;
137 }
138
139 static void addMediaEngine(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsType)
140 {
141     ASSERT(constructor);
142     ASSERT(getSupportedTypes);
143     ASSERT(supportsType);
144     installedMediaEngines().append(new MediaPlayerFactory(constructor, getSupportedTypes, supportsType));
145 }
146
147 static MediaPlayerFactory* chooseBestEngineForTypeAndCodecs(const String& type, const String& codecs)
148 {
149     Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
150
151     if (engines.isEmpty())
152         return 0;
153
154     MediaPlayerFactory* engine = 0;
155     MediaPlayer::SupportsType supported = MediaPlayer::IsNotSupported;
156
157     unsigned count = engines.size();
158     for (unsigned ndx = 0; ndx < count; ndx++) {
159         MediaPlayer::SupportsType engineSupport = engines[ndx]->supportsTypeAndCodecs(type, codecs);
160         if (engineSupport > supported) {
161             supported = engineSupport;
162             engine = engines[ndx];
163         }
164     }
165
166     return engine;
167 }
168
169 // media player
170
171 MediaPlayer::MediaPlayer(MediaPlayerClient* client)
172     : m_mediaPlayerClient(client)
173     , m_private(createNullMediaPlayer(this))
174     , m_currentMediaEngine(0)
175     , m_frameView(0)
176     , m_visible(false)
177     , m_rate(1.0f)
178     , m_volume(1.0f)
179 {
180 }
181
182 MediaPlayer::~MediaPlayer()
183 {
184 }
185
186 void MediaPlayer::load(const String& url, const String& mimeType)
187 {
188     // if we don't know the MIME type, see if the path can help
189     String type = mimeType.isEmpty() ? MIMETypeRegistry::getMIMETypeForPath(url) : mimeType;
190     String codecs = MIMETypeRegistry::getParameterFromMIMEType(type, "codecs");
191
192     MediaPlayerFactory* engine = chooseBestEngineForTypeAndCodecs(type, codecs);
193
194     // if we didn't find an engine that claims the MIME type, just use the first engine
195     if (!engine)
196         engine = installedMediaEngines()[0];
197     
198     // don't delete and recreate the player unless it comes from a different engine
199     if (engine && m_currentMediaEngine != engine) {
200         m_currentMediaEngine = engine;
201         m_private.clear();
202         m_private.set(engine->constructor(this));
203     }
204
205     if (m_private)
206         m_private->load(url);
207     else
208         m_private.set(createNullMediaPlayer(this));
209 }    
210
211 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
212 void MediaPlayer::setPoster(const String& url)
213 {
214     m_private->setPoster(url);
215 }    
216 #endif
217
218 void MediaPlayer::cancelLoad()
219 {
220     m_private->cancelLoad();
221 }    
222
223 void MediaPlayer::play()
224 {
225     m_private->play();
226 }
227
228 void MediaPlayer::pause()
229 {
230     m_private->pause();
231 }
232
233 float MediaPlayer::duration() const
234 {
235     return m_private->duration();
236 }
237
238 float MediaPlayer::currentTime() const
239 {
240     return m_private->currentTime();
241 }
242
243 void MediaPlayer::seek(float time)
244 {
245     m_private->seek(time);
246 }
247
248 bool MediaPlayer::paused() const
249 {
250     return m_private->paused();
251 }
252
253 bool MediaPlayer::seeking() const
254 {
255     return m_private->seeking();
256 }
257
258 IntSize MediaPlayer::naturalSize()
259 {
260     return m_private->naturalSize();
261 }
262
263 bool MediaPlayer::hasVideo()
264 {
265     return m_private->hasVideo();
266 }
267
268 bool MediaPlayer::inMediaDocument()
269 {
270     Frame* frame = m_frameView ? m_frameView->frame() : 0;
271     Document* document = frame ? frame->document() : 0;
272     
273     return document && document->isMediaDocument();
274 }
275
276 MediaPlayer::NetworkState MediaPlayer::networkState()
277 {
278     return m_private->networkState();
279 }
280
281 MediaPlayer::ReadyState MediaPlayer::readyState()
282 {
283     return m_private->readyState();
284 }
285
286 float MediaPlayer::volume() const
287 {
288     return m_volume;
289 }
290
291 void MediaPlayer::setVolume(float volume)
292 {
293     m_volume = volume;
294     m_private->setVolume(volume);   
295 }
296
297 float MediaPlayer::rate() const
298 {
299     return m_rate;
300 }
301
302 void MediaPlayer::setRate(float rate)
303 {
304     m_rate = rate;
305     m_private->setRate(rate);   
306 }
307
308 int MediaPlayer::dataRate() const
309 {
310     return m_private->dataRate();
311 }
312
313 void MediaPlayer::setEndTime(float time)
314 {
315     m_private->setEndTime(time);
316 }
317
318 float MediaPlayer::maxTimeBuffered()
319 {
320     return m_private->maxTimeBuffered();
321 }
322
323 float MediaPlayer::maxTimeSeekable()
324 {
325     return m_private->maxTimeSeekable();
326 }
327
328 unsigned MediaPlayer::bytesLoaded()
329 {
330     return m_private->bytesLoaded();
331 }
332
333 bool MediaPlayer::totalBytesKnown()
334 {
335     return m_private->totalBytesKnown();
336 }
337
338 unsigned MediaPlayer::totalBytes()
339 {
340     return m_private->totalBytes();
341 }
342
343 void MediaPlayer::setRect(const IntRect& r) 
344
345     m_rect = r;
346     m_private->setRect(r);
347 }
348
349 bool MediaPlayer::visible() const
350 {
351     return m_visible;
352 }
353
354 void MediaPlayer::setVisible(bool b)
355 {
356     m_visible = b;
357     m_private->setVisible(b);
358 }
359
360 void MediaPlayer::paint(GraphicsContext* p, const IntRect& r)
361 {
362     m_private->paint(p, r);
363 }
364
365 MediaPlayer::SupportsType MediaPlayer::supportsType(const String& type, const String& codecs)
366 {
367     MediaPlayerFactory* engine = chooseBestEngineForTypeAndCodecs(type, codecs);
368
369     if (!engine)
370         return IsNotSupported;
371
372     return engine->supportsTypeAndCodecs(type, codecs);
373 }
374
375 void MediaPlayer::getSupportedTypes(HashSet<String>& types)
376 {
377     Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
378     if (engines.isEmpty())
379         return;
380
381     unsigned count = engines.size();
382     for (unsigned ndx = 0; ndx < count; ndx++)
383         engines[ndx]->getSupportedTypes(types);
384
385
386 bool MediaPlayer::isAvailable()
387 {
388     return !installedMediaEngines().isEmpty();
389
390
391 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
392 void MediaPlayer::deliverNotification(MediaPlayerProxyNotificationType notification)
393 {
394     m_private->deliverNotification(notification);
395 }
396
397 void MediaPlayer::setMediaPlayerProxy(WebMediaPlayerProxy* helper)
398 {
399     m_private->setMediaPlayerProxy(helper);
400 }
401 #endif
402
403 void MediaPlayer::networkStateChanged()
404 {
405     if (m_mediaPlayerClient)
406         m_mediaPlayerClient->mediaPlayerNetworkStateChanged(this);
407 }
408
409 void MediaPlayer::readyStateChanged()
410 {
411     if (m_mediaPlayerClient)
412         m_mediaPlayerClient->mediaPlayerReadyStateChanged(this);
413 }
414
415 void MediaPlayer::volumeChanged()
416 {
417     if (m_mediaPlayerClient)
418         m_mediaPlayerClient->mediaPlayerVolumeChanged(this);
419 }
420
421 void MediaPlayer::timeChanged()
422 {
423     if (m_mediaPlayerClient)
424         m_mediaPlayerClient->mediaPlayerTimeChanged(this);
425 }
426
427 void MediaPlayer::repaint()
428 {
429     if (m_mediaPlayerClient)
430         m_mediaPlayerClient->mediaPlayerRepaint(this);
431 }
432
433 }
434 #endif