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