1/*
2 * Copyright (C) 2007, 2008, 2009, 2010, 2011 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
31#include "ContentType.h"
32#include "Document.h"
33#include "Frame.h"
34#include "FrameView.h"
35#include "IntRect.h"
36#include "MIMETypeRegistry.h"
37#include "MediaPlayerPrivate.h"
38#include "TimeRanges.h"
39
40#if PLATFORM(QT)
41#include <QtGlobal>
42#endif
43
44#if USE(GSTREAMER)
45#include "MediaPlayerPrivateGStreamer.h"
46#endif
47
48#if PLATFORM(MAC)
49#include "MediaPlayerPrivateQTKit.h"
50#if USE(AVFOUNDATION)
51#include "MediaPlayerPrivateAVFoundationObjC.h"
52#endif
53#define PlatformMediaEngineClassName MediaPlayerPrivateQTKit
54#elif OS(WINCE) && !PLATFORM(QT)
55#include "MediaPlayerPrivateWinCE.h"
56#define PlatformMediaEngineClassName MediaPlayerPrivate
57#elif PLATFORM(WIN)
58#include "MediaPlayerPrivateQuickTimeVisualContext.h"
59#define PlatformMediaEngineClassName MediaPlayerPrivateQuickTimeVisualContext
60#elif PLATFORM(QT)
61#if USE(QT_MULTIMEDIA) && !USE(GSTREAMER)
62#include "MediaPlayerPrivateQt.h"
63#define PlatformMediaEngineClassName MediaPlayerPrivateQt
64#elif !USE(GSTREAMER)
65#include "MediaPlayerPrivatePhonon.h"
66#define PlatformMediaEngineClassName MediaPlayerPrivatePhonon
67#endif
68#elif PLATFORM(CHROMIUM)
69#include "MediaPlayerPrivateChromium.h"
70#define PlatformMediaEngineClassName MediaPlayerPrivate
71#elif PLATFORM(ANDROID)
72#include "MediaPlayerPrivateAndroid.h"
73#define PlatformMediaEngineClassName MediaPlayerPrivate
74#endif
75
76namespace WebCore {
77
78const PlatformMedia NoPlatformMedia = { PlatformMedia::None, {0} };
79
80// a null player to make MediaPlayer logic simpler
81
82class NullMediaPlayerPrivate : public MediaPlayerPrivateInterface {
83public:
84    NullMediaPlayerPrivate(MediaPlayer*) { }
85
86    virtual void load(const String&) { }
87    virtual void cancelLoad() { }
88
89    virtual void prepareToPlay() { }
90    virtual void play() { }
91    virtual void pause() { }
92
93    virtual PlatformMedia platformMedia() const { return NoPlatformMedia; }
94#if USE(ACCELERATED_COMPOSITING)
95    virtual PlatformLayer* platformLayer() const { return 0; }
96#endif
97
98    virtual IntSize naturalSize() const { return IntSize(0, 0); }
99
100    virtual bool hasVideo() const { return false; }
101    virtual bool hasAudio() const { return false; }
102
103    virtual void setVisible(bool) { }
104
105    virtual float duration() const { return 0; }
106
107    virtual float currentTime() const { return 0; }
108    virtual void seek(float) { }
109    virtual bool seeking() const { return false; }
110
111    virtual void setRate(float) { }
112    virtual void setPreservesPitch(bool) { }
113    virtual bool paused() const { return false; }
114
115    virtual void setVolume(float) { }
116
117    virtual bool supportsMuting() const { return false; }
118    virtual void setMuted(bool) { }
119
120    virtual bool hasClosedCaptions() const { return false; }
121    virtual void setClosedCaptionsVisible(bool) { };
122
123    virtual MediaPlayer::NetworkState networkState() const { return MediaPlayer::Empty; }
124    virtual MediaPlayer::ReadyState readyState() const { return MediaPlayer::HaveNothing; }
125
126    virtual float maxTimeSeekable() const { return 0; }
127    virtual PassRefPtr<TimeRanges> buffered() const { return TimeRanges::create(); }
128
129    virtual unsigned totalBytes() const { return 0; }
130    virtual unsigned bytesLoaded() const { return 0; }
131
132    virtual void setSize(const IntSize&) { }
133
134    virtual void paint(GraphicsContext*, const IntRect&) { }
135
136    virtual bool canLoadPoster() const { return false; }
137    virtual void setPoster(const String&) { }
138
139#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
140    virtual void deliverNotification(MediaPlayerProxyNotificationType) { }
141    virtual void setMediaPlayerProxy(WebMediaPlayerProxy*) { }
142    virtual void setControls(bool) { }
143#endif
144
145    virtual bool hasSingleSecurityOrigin() const { return true; }
146};
147
148static MediaPlayerPrivateInterface* createNullMediaPlayer(MediaPlayer* player)
149{
150    return new NullMediaPlayerPrivate(player);
151}
152
153
154// engine support
155
156struct MediaPlayerFactory {
157    WTF_MAKE_NONCOPYABLE(MediaPlayerFactory); WTF_MAKE_FAST_ALLOCATED;
158public:
159    MediaPlayerFactory(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsTypeAndCodecs,
160        MediaEngineGetSitesInMediaCache getSitesInMediaCache, MediaEngineClearMediaCache clearMediaCache, MediaEngineClearMediaCacheForSite clearMediaCacheForSite)
161        : constructor(constructor)
162        , getSupportedTypes(getSupportedTypes)
163        , supportsTypeAndCodecs(supportsTypeAndCodecs)
164        , getSitesInMediaCache(getSitesInMediaCache)
165        , clearMediaCache(clearMediaCache)
166        , clearMediaCacheForSite(clearMediaCacheForSite)
167
168    {
169    }
170
171    CreateMediaEnginePlayer constructor;
172    MediaEngineSupportedTypes getSupportedTypes;
173    MediaEngineSupportsType supportsTypeAndCodecs;
174    MediaEngineGetSitesInMediaCache getSitesInMediaCache;
175    MediaEngineClearMediaCache clearMediaCache;
176    MediaEngineClearMediaCacheForSite clearMediaCacheForSite;
177};
178
179static void addMediaEngine(CreateMediaEnginePlayer, MediaEngineSupportedTypes, MediaEngineSupportsType, MediaEngineGetSitesInMediaCache, MediaEngineClearMediaCache, MediaEngineClearMediaCacheForSite);
180static MediaPlayerFactory* bestMediaEngineForTypeAndCodecs(const String& type, const String& codecs, MediaPlayerFactory* current = 0);
181static MediaPlayerFactory* nextMediaEngine(MediaPlayerFactory* current);
182
183static Vector<MediaPlayerFactory*>& installedMediaEngines()
184{
185    DEFINE_STATIC_LOCAL(Vector<MediaPlayerFactory*>, installedEngines, ());
186    static bool enginesQueried = false;
187
188    if (!enginesQueried) {
189        enginesQueried = true;
190
191#if USE(GSTREAMER)
192        MediaPlayerPrivateGStreamer::registerMediaEngine(addMediaEngine);
193#endif
194
195#if USE(AVFOUNDATION) && PLATFORM(MAC)
196        MediaPlayerPrivateAVFoundationObjC::registerMediaEngine(addMediaEngine);
197#endif
198
199#if !PLATFORM(GTK) && !PLATFORM(EFL) && !(PLATFORM(QT) && USE(GSTREAMER))
200        PlatformMediaEngineClassName::registerMediaEngine(addMediaEngine);
201#endif
202    }
203
204    return installedEngines;
205}
206
207static void addMediaEngine(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsType,
208    MediaEngineGetSitesInMediaCache getSitesInMediaCache, MediaEngineClearMediaCache clearMediaCache, MediaEngineClearMediaCacheForSite clearMediaCacheForSite)
209{
210    ASSERT(constructor);
211    ASSERT(getSupportedTypes);
212    ASSERT(supportsType);
213
214    installedMediaEngines().append(new MediaPlayerFactory(constructor, getSupportedTypes, supportsType, getSitesInMediaCache, clearMediaCache, clearMediaCacheForSite));
215}
216
217static const AtomicString& applicationOctetStream()
218{
219    DEFINE_STATIC_LOCAL(const AtomicString, applicationOctetStream, ("application/octet-stream"));
220    return applicationOctetStream;
221}
222
223static const AtomicString& textPlain()
224{
225    DEFINE_STATIC_LOCAL(const AtomicString, textPlain, ("text/plain"));
226    return textPlain;
227}
228
229static const AtomicString& codecs()
230{
231    DEFINE_STATIC_LOCAL(const AtomicString, codecs, ("codecs"));
232    return codecs;
233}
234
235static MediaPlayerFactory* bestMediaEngineForTypeAndCodecs(const String& type, const String& codecs, MediaPlayerFactory* current)
236{
237    if (type.isEmpty())
238        return 0;
239
240    Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
241    if (engines.isEmpty())
242        return 0;
243
244    // 4.8.10.3 MIME types - In the absence of a specification to the contrary, the MIME type "application/octet-stream"
245    // when used with parameters, e.g. "application/octet-stream;codecs=theora", is a type that the user agent knows
246    // it cannot render.
247    if (type == applicationOctetStream()) {
248        if (!codecs.isEmpty())
249            return 0;
250    }
251
252    MediaPlayerFactory* engine = 0;
253    MediaPlayer::SupportsType supported = MediaPlayer::IsNotSupported;
254    unsigned count = engines.size();
255    for (unsigned ndx = 0; ndx < count; ndx++) {
256        if (current) {
257            if (current == engines[ndx])
258                current = 0;
259            continue;
260        }
261        MediaPlayer::SupportsType engineSupport = engines[ndx]->supportsTypeAndCodecs(type, codecs);
262        if (engineSupport > supported) {
263            supported = engineSupport;
264            engine = engines[ndx];
265        }
266    }
267
268    return engine;
269}
270
271static MediaPlayerFactory* nextMediaEngine(MediaPlayerFactory* current)
272{
273    Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
274    if (engines.isEmpty())
275        return 0;
276
277    if (!current)
278        return engines.first();
279
280    size_t currentIndex = engines.find(current);
281    if (currentIndex == WTF::notFound || currentIndex == engines.size())
282        return 0;
283
284    return engines[currentIndex + 1];
285}
286
287// media player
288
289MediaPlayer::MediaPlayer(MediaPlayerClient* client)
290    : m_mediaPlayerClient(client)
291    , m_reloadTimer(this, &MediaPlayer::reloadTimerFired)
292    , m_private(createNullMediaPlayer(this))
293    , m_currentMediaEngine(0)
294    , m_frameView(0)
295    , m_preload(Auto)
296    , m_visible(false)
297    , m_rate(1.0f)
298    , m_volume(1.0f)
299    , m_muted(false)
300    , m_preservesPitch(true)
301    , m_privateBrowsing(false)
302    , m_shouldPrepareToRender(false)
303#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
304    , m_playerProxy(0)
305#endif
306#if PLATFORM(ANDROID)
307    , m_mediaElementType(Video)
308#endif
309{
310#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
311    Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
312    if (!engines.isEmpty()) {
313        m_currentMediaEngine = engines[0];
314        m_private.clear();
315        m_private.set(engines[0]->constructor(this));
316        if (m_mediaPlayerClient)
317            m_mediaPlayerClient->mediaPlayerEngineUpdated(this);
318    }
319#endif
320}
321
322MediaPlayer::~MediaPlayer()
323{
324    m_mediaPlayerClient = 0;
325}
326
327void MediaPlayer::load(const String& url, const ContentType& contentType)
328{
329    String type = contentType.type().lower();
330    String typeCodecs = contentType.parameter(codecs());
331
332    // If the MIME type is missing or is not meaningful, try to figure it out from the URL.
333    if (type.isEmpty() || type == applicationOctetStream() || type == textPlain()) {
334        if (protocolIs(url, "data"))
335            type = mimeTypeFromDataURL(url);
336        else {
337            size_t pos = url.reverseFind('.');
338            if (pos != notFound) {
339                String extension = url.substring(pos + 1);
340                String mediaType = MIMETypeRegistry::getMediaMIMETypeForExtension(extension);
341                if (!mediaType.isEmpty())
342                    type = mediaType;
343            }
344        }
345    }
346
347    m_url = url;
348    m_contentMIMEType = type;
349    m_contentTypeCodecs = typeCodecs;
350    loadWithNextMediaEngine(0);
351}
352
353void MediaPlayer::loadWithNextMediaEngine(MediaPlayerFactory* current)
354{
355    MediaPlayerFactory* engine;
356
357    // If no MIME type is specified, just use the next engine.
358    if (m_contentMIMEType.isEmpty())
359        engine = nextMediaEngine(current);
360    else
361        engine = bestMediaEngineForTypeAndCodecs(m_contentMIMEType, m_contentTypeCodecs, current);
362
363    // Don't delete and recreate the player unless it comes from a different engine.
364    if (!engine) {
365        m_currentMediaEngine = engine;
366        m_private.clear();
367    } else if (m_currentMediaEngine != engine) {
368        m_currentMediaEngine = engine;
369        m_private.clear();
370        m_private.set(engine->constructor(this));
371        if (m_mediaPlayerClient)
372            m_mediaPlayerClient->mediaPlayerEngineUpdated(this);
373#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
374        m_private->setMediaPlayerProxy(m_playerProxy);
375#endif
376        m_private->setPrivateBrowsingMode(m_privateBrowsing);
377        m_private->setPreload(m_preload);
378        m_private->setPreservesPitch(preservesPitch());
379        if (m_shouldPrepareToRender)
380            m_private->prepareForRendering();
381    }
382
383    if (m_private)
384        m_private->load(m_url);
385    else {
386        m_private.set(createNullMediaPlayer(this));
387        if (m_mediaPlayerClient)
388            m_mediaPlayerClient->mediaPlayerEngineUpdated(this);
389    }
390}
391
392bool MediaPlayer::hasAvailableVideoFrame() const
393{
394    return m_private->hasAvailableVideoFrame();
395}
396
397void MediaPlayer::prepareForRendering()
398{
399    m_shouldPrepareToRender = true;
400    m_private->prepareForRendering();
401}
402
403bool MediaPlayer::canLoadPoster() const
404{
405    return m_private->canLoadPoster();
406}
407
408void MediaPlayer::setPoster(const String& url)
409{
410    m_private->setPoster(url);
411}
412
413void MediaPlayer::cancelLoad()
414{
415    m_private->cancelLoad();
416}
417
418void MediaPlayer::prepareToPlay()
419{
420    m_private->prepareToPlay();
421}
422
423void MediaPlayer::play()
424{
425    m_private->play();
426}
427
428void MediaPlayer::pause()
429{
430    m_private->pause();
431}
432
433float MediaPlayer::duration() const
434{
435    return m_private->duration();
436}
437
438float MediaPlayer::startTime() const
439{
440    return m_private->startTime();
441}
442
443float MediaPlayer::currentTime() const
444{
445    return m_private->currentTime();
446}
447
448void MediaPlayer::seek(float time)
449{
450    m_private->seek(time);
451}
452
453bool MediaPlayer::paused() const
454{
455    return m_private->paused();
456}
457
458bool MediaPlayer::seeking() const
459{
460    return m_private->seeking();
461}
462
463bool MediaPlayer::supportsFullscreen() const
464{
465    return m_private->supportsFullscreen();
466}
467
468bool MediaPlayer::supportsSave() const
469{
470    return m_private->supportsSave();
471}
472
473IntSize MediaPlayer::naturalSize()
474{
475    return m_private->naturalSize();
476}
477
478bool MediaPlayer::hasVideo() const
479{
480    return m_private->hasVideo();
481}
482
483bool MediaPlayer::hasAudio() const
484{
485    return m_private->hasAudio();
486}
487
488bool MediaPlayer::inMediaDocument()
489{
490    Frame* frame = m_frameView ? m_frameView->frame() : 0;
491    Document* document = frame ? frame->document() : 0;
492
493    return document && document->isMediaDocument();
494}
495
496PlatformMedia MediaPlayer::platformMedia() const
497{
498    return m_private->platformMedia();
499}
500
501#if USE(ACCELERATED_COMPOSITING)
502PlatformLayer* MediaPlayer::platformLayer() const
503{
504    return m_private->platformLayer();
505}
506#endif
507
508MediaPlayer::NetworkState MediaPlayer::networkState()
509{
510    return m_private->networkState();
511}
512
513MediaPlayer::ReadyState MediaPlayer::readyState()
514{
515    return m_private->readyState();
516}
517
518float MediaPlayer::volume() const
519{
520    return m_volume;
521}
522
523void MediaPlayer::setVolume(float volume)
524{
525    m_volume = volume;
526
527    if (m_private->supportsMuting() || !m_muted)
528        m_private->setVolume(volume);
529}
530
531bool MediaPlayer::muted() const
532{
533    return m_muted;
534}
535
536void MediaPlayer::setMuted(bool muted)
537{
538    m_muted = muted;
539
540    if (m_private->supportsMuting())
541        m_private->setMuted(muted);
542    else
543        m_private->setVolume(muted ? 0 : m_volume);
544}
545
546bool MediaPlayer::hasClosedCaptions() const
547{
548    return m_private->hasClosedCaptions();
549}
550
551void MediaPlayer::setClosedCaptionsVisible(bool closedCaptionsVisible)
552{
553    m_private->setClosedCaptionsVisible(closedCaptionsVisible);
554}
555
556float MediaPlayer::rate() const
557{
558    return m_rate;
559}
560
561void MediaPlayer::setRate(float rate)
562{
563    m_rate = rate;
564    m_private->setRate(rate);
565}
566
567bool MediaPlayer::preservesPitch() const
568{
569    return m_preservesPitch;
570}
571
572void MediaPlayer::setPreservesPitch(bool preservesPitch)
573{
574    m_preservesPitch = preservesPitch;
575    m_private->setPreservesPitch(preservesPitch);
576}
577
578PassRefPtr<TimeRanges> MediaPlayer::buffered()
579{
580    return m_private->buffered();
581}
582
583float MediaPlayer::maxTimeSeekable()
584{
585    return m_private->maxTimeSeekable();
586}
587
588unsigned MediaPlayer::bytesLoaded()
589{
590    return m_private->bytesLoaded();
591}
592
593void MediaPlayer::setSize(const IntSize& size)
594{
595    m_size = size;
596    m_private->setSize(size);
597}
598
599bool MediaPlayer::visible() const
600{
601    return m_visible;
602}
603
604void MediaPlayer::setVisible(bool b)
605{
606    m_visible = b;
607    m_private->setVisible(b);
608}
609
610MediaPlayer::Preload MediaPlayer::preload() const
611{
612    return m_preload;
613}
614
615void MediaPlayer::setPreload(MediaPlayer::Preload preload)
616{
617    m_preload = preload;
618    m_private->setPreload(preload);
619}
620
621void MediaPlayer::paint(GraphicsContext* p, const IntRect& r)
622{
623    m_private->paint(p, r);
624}
625
626void MediaPlayer::paintCurrentFrameInContext(GraphicsContext* p, const IntRect& r)
627{
628    m_private->paintCurrentFrameInContext(p, r);
629}
630
631MediaPlayer::SupportsType MediaPlayer::supportsType(const ContentType& contentType)
632{
633    String type = contentType.type().lower();
634    String typeCodecs = contentType.parameter(codecs());
635
636    // 4.8.10.3 MIME types - The canPlayType(type) method must return the empty string if type is a type that the
637    // user agent knows it cannot render or is the type "application/octet-stream"
638    if (type == applicationOctetStream())
639        return IsNotSupported;
640
641    MediaPlayerFactory* engine = bestMediaEngineForTypeAndCodecs(type, typeCodecs);
642    if (!engine)
643        return IsNotSupported;
644
645    return engine->supportsTypeAndCodecs(type, typeCodecs);
646}
647
648void MediaPlayer::getSupportedTypes(HashSet<String>& types)
649{
650    Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
651    if (engines.isEmpty())
652        return;
653
654    unsigned count = engines.size();
655    for (unsigned ndx = 0; ndx < count; ndx++)
656        engines[ndx]->getSupportedTypes(types);
657}
658
659bool MediaPlayer::isAvailable()
660{
661    return !installedMediaEngines().isEmpty();
662}
663
664#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
665void MediaPlayer::deliverNotification(MediaPlayerProxyNotificationType notification)
666{
667    m_private->deliverNotification(notification);
668}
669
670void MediaPlayer::setMediaPlayerProxy(WebMediaPlayerProxy* proxy)
671{
672    m_playerProxy = proxy;
673    m_private->setMediaPlayerProxy(proxy);
674}
675
676void MediaPlayer::setControls(bool controls)
677{
678    m_private->setControls(controls);
679}
680
681void MediaPlayer::enterFullscreen()
682{
683    m_private->enterFullscreen();
684}
685
686void MediaPlayer::exitFullscreen()
687{
688    m_private->exitFullscreen();
689}
690#endif
691
692#if PLATFORM(ANDROID)
693void MediaPlayer::enterFullscreenMode()
694{
695    // Tell the player to enter full screen mode.
696    m_private->enterFullscreenMode();
697}
698#endif
699
700#if USE(ACCELERATED_COMPOSITING)
701void MediaPlayer::acceleratedRenderingStateChanged()
702{
703    m_private->acceleratedRenderingStateChanged();
704}
705
706bool MediaPlayer::supportsAcceleratedRendering() const
707{
708    return m_private->supportsAcceleratedRendering();
709}
710#endif // USE(ACCELERATED_COMPOSITING)
711
712bool MediaPlayer::hasSingleSecurityOrigin() const
713{
714    return m_private->hasSingleSecurityOrigin();
715}
716
717MediaPlayer::MovieLoadType MediaPlayer::movieLoadType() const
718{
719    return m_private->movieLoadType();
720}
721
722float MediaPlayer::mediaTimeForTimeValue(float timeValue) const
723{
724    return m_private->mediaTimeForTimeValue(timeValue);
725}
726
727double MediaPlayer::maximumDurationToCacheMediaTime() const
728{
729    return m_private->maximumDurationToCacheMediaTime();
730}
731
732unsigned MediaPlayer::decodedFrameCount() const
733{
734    return m_private->decodedFrameCount();
735}
736
737unsigned MediaPlayer::droppedFrameCount() const
738{
739    return m_private->droppedFrameCount();
740}
741
742unsigned MediaPlayer::audioDecodedByteCount() const
743{
744    return m_private->audioDecodedByteCount();
745}
746
747unsigned MediaPlayer::videoDecodedByteCount() const
748{
749    return m_private->videoDecodedByteCount();
750}
751
752void MediaPlayer::reloadTimerFired(Timer<MediaPlayer>*)
753{
754    m_private->cancelLoad();
755    loadWithNextMediaEngine(m_currentMediaEngine);
756}
757
758void MediaPlayer::getSitesInMediaCache(Vector<String>& sites)
759{
760    Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
761    unsigned size = engines.size();
762    for (unsigned i = 0; i < size; i++) {
763        if (!engines[i]->getSitesInMediaCache)
764            continue;
765        Vector<String> engineSites;
766        engines[i]->getSitesInMediaCache(engineSites);
767        sites.append(engineSites);
768    }
769}
770
771void MediaPlayer::clearMediaCache()
772{
773    Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
774    unsigned size = engines.size();
775    for (unsigned i = 0; i < size; i++) {
776        if (engines[i]->clearMediaCache)
777            engines[i]->clearMediaCache();
778    }
779}
780
781void MediaPlayer::clearMediaCacheForSite(const String& site)
782{
783    Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
784    unsigned size = engines.size();
785    for (unsigned i = 0; i < size; i++) {
786        if (engines[i]->clearMediaCacheForSite)
787            engines[i]->clearMediaCacheForSite(site);
788    }
789}
790
791void MediaPlayer::setPrivateBrowsingMode(bool privateBrowsingMode)
792{
793    m_privateBrowsing = privateBrowsingMode;
794    m_private->setPrivateBrowsingMode(m_privateBrowsing);
795}
796
797// Client callbacks.
798void MediaPlayer::networkStateChanged()
799{
800    // If more than one media engine is installed and this one failed before finding metadata,
801    // let the next engine try.
802    if (m_private->networkState() >= FormatError
803        && m_private->readyState() < HaveMetadata
804        && installedMediaEngines().size() > 1) {
805        if ( m_contentMIMEType.isEmpty() || bestMediaEngineForTypeAndCodecs(m_contentMIMEType, m_contentTypeCodecs, m_currentMediaEngine)) {
806            m_reloadTimer.startOneShot(0);
807            return;
808        }
809    }
810    if (m_mediaPlayerClient)
811        m_mediaPlayerClient->mediaPlayerNetworkStateChanged(this);
812}
813
814void MediaPlayer::readyStateChanged()
815{
816    if (m_mediaPlayerClient)
817        m_mediaPlayerClient->mediaPlayerReadyStateChanged(this);
818}
819
820void MediaPlayer::volumeChanged(float newVolume)
821{
822    m_volume = newVolume;
823    if (m_mediaPlayerClient)
824        m_mediaPlayerClient->mediaPlayerVolumeChanged(this);
825}
826
827void MediaPlayer::muteChanged(bool newMuted)
828{
829    m_muted = newMuted;
830    if (m_mediaPlayerClient)
831        m_mediaPlayerClient->mediaPlayerMuteChanged(this);
832}
833
834void MediaPlayer::timeChanged()
835{
836    if (m_mediaPlayerClient)
837        m_mediaPlayerClient->mediaPlayerTimeChanged(this);
838}
839
840void MediaPlayer::sizeChanged()
841{
842    if (m_mediaPlayerClient)
843        m_mediaPlayerClient->mediaPlayerSizeChanged(this);
844}
845
846void MediaPlayer::repaint()
847{
848    if (m_mediaPlayerClient)
849        m_mediaPlayerClient->mediaPlayerRepaint(this);
850}
851
852void MediaPlayer::durationChanged()
853{
854    if (m_mediaPlayerClient)
855        m_mediaPlayerClient->mediaPlayerDurationChanged(this);
856}
857
858void MediaPlayer::rateChanged()
859{
860    if (m_mediaPlayerClient)
861        m_mediaPlayerClient->mediaPlayerRateChanged(this);
862}
863
864void MediaPlayer::playbackStateChanged()
865{
866    if (m_mediaPlayerClient)
867        m_mediaPlayerClient->mediaPlayerPlaybackStateChanged(this);
868}
869
870void MediaPlayer::firstVideoFrameAvailable()
871{
872    if (m_mediaPlayerClient)
873        m_mediaPlayerClient->mediaPlayerFirstVideoFrameAvailable(this);
874}
875
876}
877
878#endif
879