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