1/*
2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 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 "Logging.h"
37#include "MIMETypeRegistry.h"
38#include "MediaPlayerPrivate.h"
39#include "Settings.h"
40#include "TimeRanges.h"
41#include <wtf/text/CString.h>
42
43#if ENABLE(VIDEO_TRACK)
44#include "InbandTextTrackPrivate.h"
45#endif
46
47#if ENABLE(MEDIA_SOURCE)
48#include "MediaSource.h"
49#endif
50
51#if PLATFORM(QT)
52#include <QtGlobal>
53#endif
54
55#if USE(GSTREAMER)
56#include "MediaPlayerPrivateGStreamer.h"
57#define PlatformMediaEngineClassName MediaPlayerPrivateGStreamer
58#endif
59
60#if PLATFORM(MAC)
61#include "MediaPlayerPrivateQTKit.h"
62#if USE(AVFOUNDATION)
63#include "MediaPlayerPrivateAVFoundationObjC.h"
64#endif
65#elif OS(WINCE) && !PLATFORM(QT)
66#include "MediaPlayerPrivateWinCE.h"
67#define PlatformMediaEngineClassName MediaPlayerPrivate
68#elif PLATFORM(WIN)
69#if defined(_M_IX86)
70#include "MediaPlayerPrivateQuickTimeVisualContext.h"
71#define PlatformMediaEngineClassName MediaPlayerPrivateQuickTimeVisualContext
72#endif
73#if USE(AVFOUNDATION)
74#include "MediaPlayerPrivateAVFoundationCF.h"
75#endif
76#elif PLATFORM(QT)
77#if USE(QT_MULTIMEDIA) && !USE(GSTREAMER)
78#include "MediaPlayerPrivateQt.h"
79#define PlatformMediaEngineClassName MediaPlayerPrivateQt
80#endif
81#elif PLATFORM(BLACKBERRY)
82#include "MediaPlayerPrivateBlackBerry.h"
83#define PlatformMediaEngineClassName MediaPlayerPrivate
84#endif
85
86namespace WebCore {
87
88const PlatformMedia NoPlatformMedia = { PlatformMedia::None, {0} };
89
90// a null player to make MediaPlayer logic simpler
91
92class NullMediaPlayerPrivate : public MediaPlayerPrivateInterface {
93public:
94    NullMediaPlayerPrivate(MediaPlayer*) { }
95
96    virtual void load(const String&) { }
97#if ENABLE(MEDIA_SOURCE)
98    virtual void load(const String&, PassRefPtr<MediaSource>) { }
99#endif
100    virtual void cancelLoad() { }
101
102    virtual void prepareToPlay() { }
103    virtual void play() { }
104    virtual void pause() { }
105
106    virtual PlatformMedia platformMedia() const { return NoPlatformMedia; }
107#if USE(ACCELERATED_COMPOSITING)
108    virtual PlatformLayer* platformLayer() const { return 0; }
109#endif
110
111    virtual IntSize naturalSize() const { return IntSize(0, 0); }
112
113    virtual bool hasVideo() const { return false; }
114    virtual bool hasAudio() const { return false; }
115
116    virtual void setVisible(bool) { }
117
118    virtual double durationDouble() const { return 0; }
119
120    virtual double currentTimeDouble() const { return 0; }
121    virtual void seekDouble(double) { }
122    virtual bool seeking() const { return false; }
123
124    virtual void setRateDouble(double) { }
125    virtual void setPreservesPitch(bool) { }
126    virtual bool paused() const { return false; }
127
128    virtual void setVolumeDouble(double) { }
129
130    virtual bool supportsMuting() const { return false; }
131    virtual void setMuted(bool) { }
132
133    virtual bool hasClosedCaptions() const { return false; }
134    virtual void setClosedCaptionsVisible(bool) { };
135
136    virtual MediaPlayer::NetworkState networkState() const { return MediaPlayer::Empty; }
137    virtual MediaPlayer::ReadyState readyState() const { return MediaPlayer::HaveNothing; }
138
139    virtual double maxTimeSeekableDouble() const { return 0; }
140    virtual double minTimeSeekable() const { return 0; }
141    virtual PassRefPtr<TimeRanges> buffered() const { return TimeRanges::create(); }
142
143    virtual unsigned totalBytes() const { return 0; }
144    virtual bool didLoadingProgress() const { return false; }
145
146    virtual void setSize(const IntSize&) { }
147
148    virtual void paint(GraphicsContext*, const IntRect&) { }
149
150    virtual bool canLoadPoster() const { return false; }
151    virtual void setPoster(const String&) { }
152
153#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
154    virtual void deliverNotification(MediaPlayerProxyNotificationType) { }
155    virtual void setMediaPlayerProxy(WebMediaPlayerProxy*) { }
156    virtual void setControls(bool) { }
157#endif
158
159    virtual bool hasSingleSecurityOrigin() const { return true; }
160
161#if ENABLE(ENCRYPTED_MEDIA)
162    virtual MediaPlayer::MediaKeyException generateKeyRequest(const String&, const unsigned char*, unsigned) OVERRIDE { return MediaPlayer::InvalidPlayerState; }
163    virtual MediaPlayer::MediaKeyException addKey(const String&, const unsigned char*, unsigned, const unsigned char*, unsigned, const String&) OVERRIDE { return MediaPlayer::InvalidPlayerState; }
164    virtual MediaPlayer::MediaKeyException cancelKeyRequest(const String&, const String&) OVERRIDE { return MediaPlayer::InvalidPlayerState; }
165#endif
166};
167
168static PassOwnPtr<MediaPlayerPrivateInterface> createNullMediaPlayer(MediaPlayer* player)
169{
170    return adoptPtr(new NullMediaPlayerPrivate(player));
171}
172
173
174// engine support
175
176struct MediaPlayerFactory {
177    WTF_MAKE_NONCOPYABLE(MediaPlayerFactory); WTF_MAKE_FAST_ALLOCATED;
178public:
179    MediaPlayerFactory(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsTypeAndCodecs,
180        MediaEngineGetSitesInMediaCache getSitesInMediaCache, MediaEngineClearMediaCache clearMediaCache, MediaEngineClearMediaCacheForSite clearMediaCacheForSite)
181        : constructor(constructor)
182        , getSupportedTypes(getSupportedTypes)
183        , supportsTypeAndCodecs(supportsTypeAndCodecs)
184        , getSitesInMediaCache(getSitesInMediaCache)
185        , clearMediaCache(clearMediaCache)
186        , clearMediaCacheForSite(clearMediaCacheForSite)
187    {
188    }
189
190    CreateMediaEnginePlayer constructor;
191    MediaEngineSupportedTypes getSupportedTypes;
192    MediaEngineSupportsType supportsTypeAndCodecs;
193    MediaEngineGetSitesInMediaCache getSitesInMediaCache;
194    MediaEngineClearMediaCache clearMediaCache;
195    MediaEngineClearMediaCacheForSite clearMediaCacheForSite;
196};
197
198static void addMediaEngine(CreateMediaEnginePlayer, MediaEngineSupportedTypes, MediaEngineSupportsType, MediaEngineGetSitesInMediaCache, MediaEngineClearMediaCache, MediaEngineClearMediaCacheForSite);
199
200static MediaPlayerFactory* bestMediaEngineForTypeAndCodecs(const String& type, const String& codecs, const String& keySystem, const KURL&, MediaPlayerFactory* current = 0);
201static MediaPlayerFactory* nextMediaEngine(MediaPlayerFactory* current);
202
203enum RequeryEngineOptions { DoNotResetEngines, ResetEngines };
204static Vector<MediaPlayerFactory*>& installedMediaEngines(RequeryEngineOptions requeryFlags = DoNotResetEngines )
205{
206    DEFINE_STATIC_LOCAL(Vector<MediaPlayerFactory*>, installedEngines, ());
207    static bool enginesQueried = false;
208
209    if (requeryFlags == ResetEngines) {
210        installedEngines.clear();
211        enginesQueried = false;
212        return installedEngines;
213    }
214
215    if (!enginesQueried) {
216        enginesQueried = true;
217
218#if USE(AVFOUNDATION)
219        if (Settings::isAVFoundationEnabled()) {
220#if PLATFORM(MAC)
221            MediaPlayerPrivateAVFoundationObjC::registerMediaEngine(addMediaEngine);
222#elif PLATFORM(WIN)
223            MediaPlayerPrivateAVFoundationCF::registerMediaEngine(addMediaEngine);
224#endif
225        }
226#endif
227
228#if PLATFORM(MAC)
229        if (Settings::isQTKitEnabled())
230            MediaPlayerPrivateQTKit::registerMediaEngine(addMediaEngine);
231#endif
232
233#if defined(PlatformMediaEngineClassName)
234        PlatformMediaEngineClassName::registerMediaEngine(addMediaEngine);
235#endif
236    }
237
238    return installedEngines;
239}
240
241static void addMediaEngine(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsType,
242    MediaEngineGetSitesInMediaCache getSitesInMediaCache, MediaEngineClearMediaCache clearMediaCache, MediaEngineClearMediaCacheForSite clearMediaCacheForSite)
243{
244    ASSERT(constructor);
245    ASSERT(getSupportedTypes);
246    ASSERT(supportsType);
247
248    installedMediaEngines().append(new MediaPlayerFactory(constructor, getSupportedTypes, supportsType, getSitesInMediaCache, clearMediaCache, clearMediaCacheForSite));
249}
250
251static const AtomicString& applicationOctetStream()
252{
253    DEFINE_STATIC_LOCAL(const AtomicString, applicationOctetStream, ("application/octet-stream", AtomicString::ConstructFromLiteral));
254    return applicationOctetStream;
255}
256
257static const AtomicString& textPlain()
258{
259    DEFINE_STATIC_LOCAL(const AtomicString, textPlain, ("text/plain", AtomicString::ConstructFromLiteral));
260    return textPlain;
261}
262
263static const AtomicString& codecs()
264{
265    DEFINE_STATIC_LOCAL(const AtomicString, codecs, ("codecs", AtomicString::ConstructFromLiteral));
266    return codecs;
267}
268
269static MediaPlayerFactory* bestMediaEngineForTypeAndCodecs(const String& type, const String& codecs, const String& keySystem, const KURL& url, MediaPlayerFactory* current)
270{
271    if (type.isEmpty())
272        return 0;
273
274    Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
275    if (engines.isEmpty())
276        return 0;
277
278    // 4.8.10.3 MIME types - In the absence of a specification to the contrary, the MIME type "application/octet-stream"
279    // when used with parameters, e.g. "application/octet-stream;codecs=theora", is a type that the user agent knows
280    // it cannot render.
281    if (type == applicationOctetStream()) {
282        if (!codecs.isEmpty())
283            return 0;
284    }
285
286    MediaPlayerFactory* engine = 0;
287    MediaPlayer::SupportsType supported = MediaPlayer::IsNotSupported;
288    unsigned count = engines.size();
289    for (unsigned ndx = 0; ndx < count; ndx++) {
290        if (current) {
291            if (current == engines[ndx])
292                current = 0;
293            continue;
294        }
295#if ENABLE(ENCRYPTED_MEDIA) || ENABLE(ENCRYPTED_MEDIA_V2)
296        MediaPlayer::SupportsType engineSupport = engines[ndx]->supportsTypeAndCodecs(type, codecs, keySystem, url);
297#else
298        UNUSED_PARAM(keySystem);
299        ASSERT(keySystem.isEmpty());
300        MediaPlayer::SupportsType engineSupport = engines[ndx]->supportsTypeAndCodecs(type, codecs, url);
301#endif
302        if (engineSupport > supported) {
303            supported = engineSupport;
304            engine = engines[ndx];
305        }
306    }
307
308    return engine;
309}
310
311static MediaPlayerFactory* nextMediaEngine(MediaPlayerFactory* current)
312{
313    Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
314    if (engines.isEmpty())
315        return 0;
316
317    if (!current)
318        return engines.first();
319
320    size_t currentIndex = engines.find(current);
321    if (currentIndex == WTF::notFound || currentIndex + 1 >= engines.size())
322        return 0;
323
324    return engines[currentIndex + 1];
325}
326
327// media player
328
329MediaPlayer::MediaPlayer(MediaPlayerClient* client)
330    : m_mediaPlayerClient(client)
331    , m_reloadTimer(this, &MediaPlayer::reloadTimerFired)
332    , m_private(createNullMediaPlayer(this))
333    , m_currentMediaEngine(0)
334    , m_frameView(0)
335    , m_preload(Auto)
336    , m_visible(false)
337    , m_rate(1.0f)
338    , m_volume(1.0f)
339    , m_muted(false)
340    , m_preservesPitch(true)
341    , m_privateBrowsing(false)
342    , m_shouldPrepareToRender(false)
343    , m_contentMIMETypeWasInferredFromExtension(false)
344#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
345    , m_playerProxy(0)
346#endif
347{
348#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
349    Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
350    if (!engines.isEmpty()) {
351        m_currentMediaEngine = engines[0];
352        m_private = engines[0]->constructor(this);
353        if (m_mediaPlayerClient)
354            m_mediaPlayerClient->mediaPlayerEngineUpdated(this);
355    }
356#endif
357}
358
359MediaPlayer::~MediaPlayer()
360{
361    m_mediaPlayerClient = 0;
362}
363
364bool MediaPlayer::load(const KURL& url, const ContentType& contentType, const String& keySystem)
365{
366    m_contentMIMEType = contentType.type().lower();
367    m_contentTypeCodecs = contentType.parameter(codecs());
368    m_url = url;
369    m_keySystem = keySystem.lower();
370    m_contentMIMETypeWasInferredFromExtension = false;
371
372#if ENABLE(MEDIA_SOURCE)
373    m_mediaSource = 0;
374#endif
375
376    // If the MIME type is missing or is not meaningful, try to figure it out from the URL.
377    if (m_contentMIMEType.isEmpty() || m_contentMIMEType == applicationOctetStream() || m_contentMIMEType == textPlain()) {
378        if (m_url.protocolIsData())
379            m_contentMIMEType = mimeTypeFromDataURL(m_url.string());
380        else {
381            String lastPathComponent = url.lastPathComponent();
382            size_t pos = lastPathComponent.reverseFind('.');
383            if (pos != notFound) {
384                String extension = lastPathComponent.substring(pos + 1);
385                String mediaType = MIMETypeRegistry::getMediaMIMETypeForExtension(extension);
386                if (!mediaType.isEmpty()) {
387                    m_contentMIMEType = mediaType;
388                    m_contentMIMETypeWasInferredFromExtension = true;
389                }
390            }
391        }
392    }
393
394    loadWithNextMediaEngine(0);
395    return m_currentMediaEngine;
396}
397
398#if ENABLE(MEDIA_SOURCE)
399bool MediaPlayer::load(const KURL& url, PassRefPtr<MediaSource> mediaSource)
400{
401    m_mediaSource = mediaSource;
402    m_contentMIMEType = "";
403    m_contentTypeCodecs = "";
404    m_url = url;
405    m_keySystem = "";
406    m_contentMIMETypeWasInferredFromExtension = false;
407    loadWithNextMediaEngine(0);
408    return m_currentMediaEngine;
409}
410#endif
411
412void MediaPlayer::loadWithNextMediaEngine(MediaPlayerFactory* current)
413{
414    MediaPlayerFactory* engine = 0;
415
416    if (!m_contentMIMEType.isEmpty())
417        engine = bestMediaEngineForTypeAndCodecs(m_contentMIMEType, m_contentTypeCodecs, m_keySystem, m_url, current);
418
419    // If no MIME type is specified or the type was inferred from the file extension, just use the next engine.
420    if (!engine && (m_contentMIMEType.isEmpty() || m_contentMIMETypeWasInferredFromExtension))
421        engine = nextMediaEngine(current);
422
423    // Don't delete and recreate the player unless it comes from a different engine.
424    if (!engine) {
425        LOG(Media, "MediaPlayer::loadWithNextMediaEngine - no media engine found for type \"%s\"", m_contentMIMEType.utf8().data());
426        m_currentMediaEngine = engine;
427        m_private = nullptr;
428    } else if (m_currentMediaEngine != engine) {
429        m_currentMediaEngine = engine;
430        m_private = engine->constructor(this);
431        if (m_mediaPlayerClient)
432            m_mediaPlayerClient->mediaPlayerEngineUpdated(this);
433#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
434        m_private->setMediaPlayerProxy(m_playerProxy);
435#endif
436        m_private->setPrivateBrowsingMode(m_privateBrowsing);
437        m_private->setPreload(m_preload);
438        m_private->setPreservesPitch(preservesPitch());
439        if (m_shouldPrepareToRender)
440            m_private->prepareForRendering();
441    }
442
443    if (m_private) {
444#if ENABLE(MEDIA_SOURCE)
445        if (m_mediaSource)
446            m_private->load(m_url.string(), m_mediaSource);
447        else
448#endif
449        m_private->load(m_url.string());
450    } else {
451        m_private = createNullMediaPlayer(this);
452        if (m_mediaPlayerClient) {
453            m_mediaPlayerClient->mediaPlayerEngineUpdated(this);
454            m_mediaPlayerClient->mediaPlayerResourceNotSupported(this);
455        }
456    }
457}
458
459bool MediaPlayer::hasAvailableVideoFrame() const
460{
461    return m_private->hasAvailableVideoFrame();
462}
463
464void MediaPlayer::prepareForRendering()
465{
466    m_shouldPrepareToRender = true;
467    m_private->prepareForRendering();
468}
469
470bool MediaPlayer::canLoadPoster() const
471{
472    return m_private->canLoadPoster();
473}
474
475void MediaPlayer::setPoster(const String& url)
476{
477    m_private->setPoster(url);
478}
479
480void MediaPlayer::cancelLoad()
481{
482    m_private->cancelLoad();
483}
484
485void MediaPlayer::prepareToPlay()
486{
487    m_private->prepareToPlay();
488}
489
490void MediaPlayer::play()
491{
492    m_private->play();
493}
494
495void MediaPlayer::pause()
496{
497    m_private->pause();
498}
499
500#if ENABLE(ENCRYPTED_MEDIA)
501MediaPlayer::MediaKeyException MediaPlayer::generateKeyRequest(const String& keySystem, const unsigned char* initData, unsigned initDataLength)
502{
503    return m_private->generateKeyRequest(keySystem.lower(), initData, initDataLength);
504}
505
506MediaPlayer::MediaKeyException MediaPlayer::addKey(const String& keySystem, const unsigned char* key, unsigned keyLength, const unsigned char* initData, unsigned initDataLength, const String& sessionId)
507{
508    return m_private->addKey(keySystem.lower(), key, keyLength, initData, initDataLength, sessionId);
509}
510
511MediaPlayer::MediaKeyException MediaPlayer::cancelKeyRequest(const String& keySystem, const String& sessionId)
512{
513    return m_private->cancelKeyRequest(keySystem.lower(), sessionId);
514}
515#endif
516
517double MediaPlayer::duration() const
518{
519    return m_private->durationDouble();
520}
521
522double MediaPlayer::startTime() const
523{
524    return m_private->startTimeDouble();
525}
526
527double MediaPlayer::initialTime() const
528{
529    return m_private->initialTime();
530}
531
532double MediaPlayer::currentTime() const
533{
534    return m_private->currentTimeDouble();
535}
536
537void MediaPlayer::seek(double time)
538{
539    m_private->seekDouble(time);
540}
541
542bool MediaPlayer::paused() const
543{
544    return m_private->paused();
545}
546
547bool MediaPlayer::seeking() const
548{
549    return m_private->seeking();
550}
551
552bool MediaPlayer::supportsFullscreen() const
553{
554    return m_private->supportsFullscreen();
555}
556
557bool MediaPlayer::supportsSave() const
558{
559    return m_private->supportsSave();
560}
561
562bool MediaPlayer::supportsScanning() const
563{
564    return m_private->supportsScanning();
565}
566
567bool MediaPlayer::requiresImmediateCompositing() const
568{
569    return m_private->requiresImmediateCompositing();
570}
571
572IntSize MediaPlayer::naturalSize()
573{
574    return m_private->naturalSize();
575}
576
577bool MediaPlayer::hasVideo() const
578{
579    return m_private->hasVideo();
580}
581
582bool MediaPlayer::hasAudio() const
583{
584    return m_private->hasAudio();
585}
586
587bool MediaPlayer::inMediaDocument()
588{
589    Frame* frame = m_frameView ? m_frameView->frame() : 0;
590    Document* document = frame ? frame->document() : 0;
591
592    return document && document->isMediaDocument();
593}
594
595PlatformMedia MediaPlayer::platformMedia() const
596{
597    return m_private->platformMedia();
598}
599
600#if USE(ACCELERATED_COMPOSITING)
601PlatformLayer* MediaPlayer::platformLayer() const
602{
603    return m_private->platformLayer();
604}
605#endif
606
607MediaPlayer::NetworkState MediaPlayer::networkState()
608{
609    return m_private->networkState();
610}
611
612MediaPlayer::ReadyState MediaPlayer::readyState()
613{
614    return m_private->readyState();
615}
616
617double MediaPlayer::volume() const
618{
619    return m_volume;
620}
621
622void MediaPlayer::setVolume(double volume)
623{
624    m_volume = volume;
625
626    if (m_private->supportsMuting() || !m_muted)
627        m_private->setVolumeDouble(volume);
628}
629
630bool MediaPlayer::muted() const
631{
632    return m_muted;
633}
634
635void MediaPlayer::setMuted(bool muted)
636{
637    m_muted = muted;
638
639    if (m_private->supportsMuting())
640        m_private->setMuted(muted);
641    else
642        m_private->setVolume(muted ? 0 : m_volume);
643}
644
645bool MediaPlayer::hasClosedCaptions() const
646{
647    return m_private->hasClosedCaptions();
648}
649
650void MediaPlayer::setClosedCaptionsVisible(bool closedCaptionsVisible)
651{
652    m_private->setClosedCaptionsVisible(closedCaptionsVisible);
653}
654
655double MediaPlayer::rate() const
656{
657    return m_rate;
658}
659
660void MediaPlayer::setRate(double rate)
661{
662    m_rate = rate;
663    m_private->setRateDouble(rate);
664}
665
666bool MediaPlayer::preservesPitch() const
667{
668    return m_preservesPitch;
669}
670
671void MediaPlayer::setPreservesPitch(bool preservesPitch)
672{
673    m_preservesPitch = preservesPitch;
674    m_private->setPreservesPitch(preservesPitch);
675}
676
677PassRefPtr<TimeRanges> MediaPlayer::buffered()
678{
679    return m_private->buffered();
680}
681
682PassRefPtr<TimeRanges> MediaPlayer::seekable()
683{
684    return m_private->seekable();
685}
686
687double MediaPlayer::maxTimeSeekable()
688{
689    return m_private->maxTimeSeekableDouble();
690}
691
692double MediaPlayer::minTimeSeekable()
693{
694    return m_private->minTimeSeekable();
695}
696
697bool MediaPlayer::didLoadingProgress()
698{
699    return m_private->didLoadingProgress();
700}
701
702void MediaPlayer::setSize(const IntSize& size)
703{
704    m_size = size;
705    m_private->setSize(size);
706}
707
708bool MediaPlayer::visible() const
709{
710    return m_visible;
711}
712
713void MediaPlayer::setVisible(bool b)
714{
715    m_visible = b;
716    m_private->setVisible(b);
717}
718
719MediaPlayer::Preload MediaPlayer::preload() const
720{
721    return m_preload;
722}
723
724void MediaPlayer::setPreload(MediaPlayer::Preload preload)
725{
726    m_preload = preload;
727    m_private->setPreload(preload);
728}
729
730void MediaPlayer::paint(GraphicsContext* p, const IntRect& r)
731{
732    m_private->paint(p, r);
733}
734
735void MediaPlayer::paintCurrentFrameInContext(GraphicsContext* p, const IntRect& r)
736{
737    m_private->paintCurrentFrameInContext(p, r);
738}
739
740bool MediaPlayer::copyVideoTextureToPlatformTexture(GraphicsContext3D* context, Platform3DObject texture, GC3Dint level, GC3Denum type, GC3Denum internalFormat, bool premultiplyAlpha, bool flipY)
741{
742    return m_private->copyVideoTextureToPlatformTexture(context, texture, level, type, internalFormat, premultiplyAlpha, flipY);
743}
744
745MediaPlayer::SupportsType MediaPlayer::supportsType(const ContentType& contentType, const String& keySystem, const KURL& url, const MediaPlayerSupportsTypeClient* client)
746{
747    String type = contentType.type().lower();
748    // The codecs string is not lower-cased because MP4 values are case sensitive
749    // per http://tools.ietf.org/html/rfc4281#page-7.
750    String typeCodecs = contentType.parameter(codecs());
751    String system = keySystem.lower();
752
753    // 4.8.10.3 MIME types - The canPlayType(type) method must return the empty string if type is a type that the
754    // user agent knows it cannot render or is the type "application/octet-stream"
755    if (type == applicationOctetStream())
756        return IsNotSupported;
757
758    MediaPlayerFactory* engine = bestMediaEngineForTypeAndCodecs(type, typeCodecs, system, url);
759    if (!engine)
760        return IsNotSupported;
761
762#if PLATFORM(MAC)
763    // YouTube will ask if the HTMLMediaElement canPlayType video/webm, then
764    // video/x-flv, then finally video/mp4, and will then load a URL of the first type
765    // in that list which returns "probably". When Perian is installed,
766    // MediaPlayerPrivateQTKit claims to support both video/webm and video/x-flv, but
767    // due to a bug in Perian, loading media in these formats will sometimes fail on
768    // slow connections. <https://bugs.webkit.org/show_bug.cgi?id=86409>
769    if (client && client->mediaPlayerNeedsSiteSpecificHacks()) {
770        String host = client->mediaPlayerDocumentHost();
771        if ((host.endsWith(".youtube.com", false) || equalIgnoringCase("youtube.com", host))
772            && (contentType.type().startsWith("video/webm", false) || contentType.type().startsWith("video/x-flv", false)))
773            return IsNotSupported;
774    }
775#else
776    UNUSED_PARAM(client);
777#endif
778
779#if ENABLE(ENCRYPTED_MEDIA) || ENABLE(ENCRYPTED_MEDIA_V2)
780    return engine->supportsTypeAndCodecs(type, typeCodecs, system, url);
781#else
782    ASSERT(system.isEmpty());
783    return engine->supportsTypeAndCodecs(type, typeCodecs, url);
784#endif
785}
786
787void MediaPlayer::getSupportedTypes(HashSet<String>& types)
788{
789    Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
790    if (engines.isEmpty())
791        return;
792
793    unsigned count = engines.size();
794    for (unsigned ndx = 0; ndx < count; ndx++)
795        engines[ndx]->getSupportedTypes(types);
796}
797
798bool MediaPlayer::isAvailable()
799{
800    return !installedMediaEngines().isEmpty();
801}
802
803#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
804void MediaPlayer::deliverNotification(MediaPlayerProxyNotificationType notification)
805{
806    m_private->deliverNotification(notification);
807}
808
809void MediaPlayer::setMediaPlayerProxy(WebMediaPlayerProxy* proxy)
810{
811    m_playerProxy = proxy;
812    m_private->setMediaPlayerProxy(proxy);
813}
814
815void MediaPlayer::setControls(bool controls)
816{
817    m_private->setControls(controls);
818}
819#endif
820
821#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) || USE(NATIVE_FULLSCREEN_VIDEO)
822void MediaPlayer::enterFullscreen()
823{
824    m_private->enterFullscreen();
825}
826
827void MediaPlayer::exitFullscreen()
828{
829    m_private->exitFullscreen();
830}
831#endif
832
833#if USE(NATIVE_FULLSCREEN_VIDEO)
834bool MediaPlayer::canEnterFullscreen() const
835{
836    return m_private->canEnterFullscreen();
837}
838#endif
839
840#if USE(ACCELERATED_COMPOSITING)
841void MediaPlayer::acceleratedRenderingStateChanged()
842{
843    m_private->acceleratedRenderingStateChanged();
844}
845
846bool MediaPlayer::supportsAcceleratedRendering() const
847{
848    return m_private->supportsAcceleratedRendering();
849}
850#endif // USE(ACCELERATED_COMPOSITING)
851
852bool MediaPlayer::hasSingleSecurityOrigin() const
853{
854    return m_private->hasSingleSecurityOrigin();
855}
856
857bool MediaPlayer::didPassCORSAccessCheck() const
858{
859    return m_private->didPassCORSAccessCheck();
860}
861
862MediaPlayer::MovieLoadType MediaPlayer::movieLoadType() const
863{
864    return m_private->movieLoadType();
865}
866
867double MediaPlayer::mediaTimeForTimeValue(double timeValue) const
868{
869    return m_private->mediaTimeForTimeValueDouble(timeValue);
870}
871
872double MediaPlayer::maximumDurationToCacheMediaTime() const
873{
874    return m_private->maximumDurationToCacheMediaTime();
875}
876
877unsigned MediaPlayer::decodedFrameCount() const
878{
879    return m_private->decodedFrameCount();
880}
881
882unsigned MediaPlayer::droppedFrameCount() const
883{
884    return m_private->droppedFrameCount();
885}
886
887unsigned MediaPlayer::audioDecodedByteCount() const
888{
889    return m_private->audioDecodedByteCount();
890}
891
892unsigned MediaPlayer::videoDecodedByteCount() const
893{
894    return m_private->videoDecodedByteCount();
895}
896
897void MediaPlayer::reloadTimerFired(Timer<MediaPlayer>*)
898{
899    m_private->cancelLoad();
900    loadWithNextMediaEngine(m_currentMediaEngine);
901}
902
903void MediaPlayer::getSitesInMediaCache(Vector<String>& sites)
904{
905    Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
906    unsigned size = engines.size();
907    for (unsigned i = 0; i < size; i++) {
908        if (!engines[i]->getSitesInMediaCache)
909            continue;
910        Vector<String> engineSites;
911        engines[i]->getSitesInMediaCache(engineSites);
912        sites.appendVector(engineSites);
913    }
914}
915
916void MediaPlayer::clearMediaCache()
917{
918    Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
919    unsigned size = engines.size();
920    for (unsigned i = 0; i < size; i++) {
921        if (engines[i]->clearMediaCache)
922            engines[i]->clearMediaCache();
923    }
924}
925
926void MediaPlayer::clearMediaCacheForSite(const String& site)
927{
928    Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
929    unsigned size = engines.size();
930    for (unsigned i = 0; i < size; i++) {
931        if (engines[i]->clearMediaCacheForSite)
932            engines[i]->clearMediaCacheForSite(site);
933    }
934}
935
936void MediaPlayer::setPrivateBrowsingMode(bool privateBrowsingMode)
937{
938    m_privateBrowsing = privateBrowsingMode;
939    m_private->setPrivateBrowsingMode(m_privateBrowsing);
940}
941
942// Client callbacks.
943void MediaPlayer::networkStateChanged()
944{
945    // If more than one media engine is installed and this one failed before finding metadata,
946    // let the next engine try.
947    if (m_private->networkState() >= FormatError
948        && m_private->readyState() < HaveMetadata
949        && installedMediaEngines().size() > 1) {
950        if (m_contentMIMEType.isEmpty() || bestMediaEngineForTypeAndCodecs(m_contentMIMEType, m_contentTypeCodecs, m_keySystem, m_url, m_currentMediaEngine)) {
951            m_reloadTimer.startOneShot(0);
952            return;
953        }
954    }
955    if (m_mediaPlayerClient)
956        m_mediaPlayerClient->mediaPlayerNetworkStateChanged(this);
957}
958
959void MediaPlayer::readyStateChanged()
960{
961    if (m_mediaPlayerClient)
962        m_mediaPlayerClient->mediaPlayerReadyStateChanged(this);
963}
964
965void MediaPlayer::volumeChanged(double newVolume)
966{
967    m_volume = newVolume;
968    if (m_mediaPlayerClient)
969        m_mediaPlayerClient->mediaPlayerVolumeChanged(this);
970}
971
972void MediaPlayer::muteChanged(bool newMuted)
973{
974    m_muted = newMuted;
975    if (m_mediaPlayerClient)
976        m_mediaPlayerClient->mediaPlayerMuteChanged(this);
977}
978
979void MediaPlayer::timeChanged()
980{
981    if (m_mediaPlayerClient)
982        m_mediaPlayerClient->mediaPlayerTimeChanged(this);
983}
984
985void MediaPlayer::sizeChanged()
986{
987    if (m_mediaPlayerClient)
988        m_mediaPlayerClient->mediaPlayerSizeChanged(this);
989}
990
991void MediaPlayer::repaint()
992{
993    if (m_mediaPlayerClient)
994        m_mediaPlayerClient->mediaPlayerRepaint(this);
995}
996
997void MediaPlayer::durationChanged()
998{
999    if (m_mediaPlayerClient)
1000        m_mediaPlayerClient->mediaPlayerDurationChanged(this);
1001}
1002
1003void MediaPlayer::rateChanged()
1004{
1005    if (m_mediaPlayerClient)
1006        m_mediaPlayerClient->mediaPlayerRateChanged(this);
1007}
1008
1009void MediaPlayer::playbackStateChanged()
1010{
1011    if (m_mediaPlayerClient)
1012        m_mediaPlayerClient->mediaPlayerPlaybackStateChanged(this);
1013}
1014
1015void MediaPlayer::firstVideoFrameAvailable()
1016{
1017    if (m_mediaPlayerClient)
1018        m_mediaPlayerClient->mediaPlayerFirstVideoFrameAvailable(this);
1019}
1020
1021void MediaPlayer::characteristicChanged()
1022{
1023    if (m_mediaPlayerClient)
1024        m_mediaPlayerClient->mediaPlayerCharacteristicChanged(this);
1025}
1026
1027#if ENABLE(WEB_AUDIO)
1028AudioSourceProvider* MediaPlayer::audioSourceProvider()
1029{
1030    return m_private->audioSourceProvider();
1031}
1032#endif // WEB_AUDIO
1033
1034#if ENABLE(ENCRYPTED_MEDIA)
1035void MediaPlayer::keyAdded(const String& keySystem, const String& sessionId)
1036{
1037    if (m_mediaPlayerClient)
1038        m_mediaPlayerClient->mediaPlayerKeyAdded(this, keySystem, sessionId);
1039}
1040
1041void MediaPlayer::keyError(const String& keySystem, const String& sessionId, MediaPlayerClient::MediaKeyErrorCode errorCode, unsigned short systemCode)
1042{
1043    if (m_mediaPlayerClient)
1044        m_mediaPlayerClient->mediaPlayerKeyError(this, keySystem, sessionId, errorCode, systemCode);
1045}
1046
1047void MediaPlayer::keyMessage(const String& keySystem, const String& sessionId, const unsigned char* message, unsigned messageLength, const KURL& defaultURL)
1048{
1049    if (m_mediaPlayerClient)
1050        m_mediaPlayerClient->mediaPlayerKeyMessage(this, keySystem, sessionId, message, messageLength, defaultURL);
1051}
1052
1053bool MediaPlayer::keyNeeded(const String& keySystem, const String& sessionId, const unsigned char* initData, unsigned initDataLength)
1054{
1055    if (m_mediaPlayerClient)
1056        return m_mediaPlayerClient->mediaPlayerKeyNeeded(this, keySystem, sessionId, initData, initDataLength);
1057    return false;
1058}
1059#endif
1060
1061#if ENABLE(ENCRYPTED_MEDIA_V2)
1062bool MediaPlayer::keyNeeded(Uint8Array* initData)
1063{
1064    if (m_mediaPlayerClient)
1065        return m_mediaPlayerClient->mediaPlayerKeyNeeded(this, initData);
1066    return false;
1067}
1068#endif
1069
1070String MediaPlayer::referrer() const
1071{
1072    if (!m_mediaPlayerClient)
1073        return String();
1074
1075    return m_mediaPlayerClient->mediaPlayerReferrer();
1076}
1077
1078String MediaPlayer::userAgent() const
1079{
1080    if (!m_mediaPlayerClient)
1081        return String();
1082
1083    return m_mediaPlayerClient->mediaPlayerUserAgent();
1084}
1085
1086String MediaPlayer::engineDescription() const
1087{
1088    if (!m_private)
1089        return String();
1090
1091    return m_private->engineDescription();
1092}
1093
1094#if PLATFORM(WIN) && USE(AVFOUNDATION)
1095GraphicsDeviceAdapter* MediaPlayer::graphicsDeviceAdapter() const
1096{
1097    if (!m_mediaPlayerClient)
1098        return 0;
1099
1100    return m_mediaPlayerClient->mediaPlayerGraphicsDeviceAdapter(this);
1101}
1102#endif
1103
1104CachedResourceLoader* MediaPlayer::cachedResourceLoader()
1105{
1106    if (!m_mediaPlayerClient)
1107        return 0;
1108
1109    return m_mediaPlayerClient->mediaPlayerCachedResourceLoader();
1110}
1111
1112#if ENABLE(VIDEO_TRACK)
1113void MediaPlayer::addAudioTrack(PassRefPtr<AudioTrackPrivate> track)
1114{
1115    if (!m_mediaPlayerClient)
1116        return;
1117
1118    m_mediaPlayerClient->mediaPlayerDidAddAudioTrack(track);
1119}
1120
1121void MediaPlayer::removeAudioTrack(PassRefPtr<AudioTrackPrivate> track)
1122{
1123    if (!m_mediaPlayerClient)
1124        return;
1125
1126    m_mediaPlayerClient->mediaPlayerDidRemoveAudioTrack(track);
1127}
1128
1129void MediaPlayer::addTextTrack(PassRefPtr<InbandTextTrackPrivate> track)
1130{
1131    if (!m_mediaPlayerClient)
1132        return;
1133
1134    m_mediaPlayerClient->mediaPlayerDidAddTextTrack(track);
1135}
1136
1137void MediaPlayer::removeTextTrack(PassRefPtr<InbandTextTrackPrivate> track)
1138{
1139    if (!m_mediaPlayerClient)
1140        return;
1141
1142    m_mediaPlayerClient->mediaPlayerDidRemoveTextTrack(track);
1143}
1144
1145void MediaPlayer::addVideoTrack(PassRefPtr<VideoTrackPrivate> track)
1146{
1147    if (!m_mediaPlayerClient)
1148        return;
1149
1150    m_mediaPlayerClient->mediaPlayerDidAddVideoTrack(track);
1151}
1152
1153void MediaPlayer::removeVideoTrack(PassRefPtr<VideoTrackPrivate> track)
1154{
1155    if (!m_mediaPlayerClient)
1156        return;
1157
1158    m_mediaPlayerClient->mediaPlayerDidRemoveVideoTrack(track);
1159}
1160
1161bool MediaPlayer::requiresTextTrackRepresentation() const
1162{
1163    return m_private->requiresTextTrackRepresentation();
1164}
1165
1166void MediaPlayer::setTextTrackRepresentation(TextTrackRepresentation* representation)
1167{
1168    m_private->setTextTrackRepresentation(representation);
1169}
1170#endif // ENABLE(VIDEO_TRACK)
1171
1172#if USE(PLATFORM_TEXT_TRACK_MENU)
1173bool MediaPlayer::implementsTextTrackControls() const
1174{
1175    return m_private->implementsTextTrackControls();
1176}
1177
1178PassRefPtr<PlatformTextTrackMenuInterface> MediaPlayer::textTrackMenu()
1179{
1180    return m_private->textTrackMenu();
1181}
1182#endif // USE(PLATFORM_TEXT_TRACK_MENU)
1183
1184void MediaPlayer::resetMediaEngines()
1185{
1186    installedMediaEngines(ResetEngines);
1187}
1188
1189#if USE(GSTREAMER)
1190void MediaPlayer::simulateAudioInterruption()
1191{
1192    if (!m_private)
1193        return;
1194
1195    m_private->simulateAudioInterruption();
1196}
1197#endif
1198
1199String MediaPlayer::languageOfPrimaryAudioTrack() const
1200{
1201    if (!m_private)
1202        return emptyString();
1203
1204    return m_private->languageOfPrimaryAudioTrack();
1205}
1206
1207size_t MediaPlayer::extraMemoryCost() const
1208{
1209    if (!m_private)
1210        return 0;
1211
1212    return m_private->extraMemoryCost();
1213}
1214
1215}
1216
1217#endif
1218