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