eb520634713236f383e15ba4579e0d540af926c1
[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 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 "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     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     DEFINE_STATIC_LOCAL(const AtomicString, applicationOctetStream, ("application/octet-stream", AtomicString::ConstructFromLiteral));
254     return applicationOctetStream;
255 }
256
257 static const AtomicString& textPlain()
258 {
259     DEFINE_STATIC_LOCAL(const AtomicString, textPlain, ("text/plain", AtomicString::ConstructFromLiteral));
260     return textPlain;
261 }
262
263 static const AtomicString& codecs()
264 {
265     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 MediaPlayer::NetworkState MediaPlayer::networkState()
629 {
630     return m_private->networkState();
631 }
632
633 MediaPlayer::ReadyState MediaPlayer::readyState()
634 {
635     return m_private->readyState();
636 }
637
638 double MediaPlayer::volume() const
639 {
640     return m_volume;
641 }
642
643 void MediaPlayer::setVolume(double volume)
644 {
645     m_volume = volume;
646
647     if (m_private->supportsMuting() || !m_muted)
648         m_private->setVolumeDouble(volume);
649 }
650
651 bool MediaPlayer::muted() const
652 {
653     return m_muted;
654 }
655
656 void MediaPlayer::setMuted(bool muted)
657 {
658     m_muted = muted;
659
660     if (m_private->supportsMuting())
661         m_private->setMuted(muted);
662     else
663         m_private->setVolume(muted ? 0 : m_volume);
664 }
665
666 bool MediaPlayer::hasClosedCaptions() const
667 {
668     return m_private->hasClosedCaptions();
669 }
670
671 void MediaPlayer::setClosedCaptionsVisible(bool closedCaptionsVisible)
672 {
673     m_private->setClosedCaptionsVisible(closedCaptionsVisible);
674 }
675
676 double MediaPlayer::rate() const
677 {
678     return m_rate;
679 }
680
681 void MediaPlayer::setRate(double rate)
682 {
683     m_rate = rate;
684     m_private->setRateDouble(rate);
685 }
686
687 bool MediaPlayer::preservesPitch() const
688 {
689     return m_preservesPitch;
690 }
691
692 void MediaPlayer::setPreservesPitch(bool preservesPitch)
693 {
694     m_preservesPitch = preservesPitch;
695     m_private->setPreservesPitch(preservesPitch);
696 }
697
698 std::unique_ptr<PlatformTimeRanges> MediaPlayer::buffered()
699 {
700     return m_private->buffered();
701 }
702
703 std::unique_ptr<PlatformTimeRanges> MediaPlayer::seekable()
704 {
705     return m_private->seekable();
706 }
707
708 double MediaPlayer::maxTimeSeekable()
709 {
710     return m_private->maxTimeSeekableDouble();
711 }
712
713 double MediaPlayer::minTimeSeekable()
714 {
715     return m_private->minTimeSeekable();
716 }
717
718 bool MediaPlayer::didLoadingProgress()
719 {
720     return m_private->didLoadingProgress();
721 }
722
723 void MediaPlayer::setSize(const IntSize& size)
724
725     m_size = size;
726     m_private->setSize(size);
727 }
728
729 bool MediaPlayer::visible() const
730 {
731     return m_visible;
732 }
733
734 void MediaPlayer::setVisible(bool b)
735 {
736     m_visible = b;
737     m_private->setVisible(b);
738 }
739
740 MediaPlayer::Preload MediaPlayer::preload() const
741 {
742     return m_preload;
743 }
744
745 void MediaPlayer::setPreload(MediaPlayer::Preload preload)
746 {
747     m_preload = preload;
748     m_private->setPreload(preload);
749 }
750
751 void MediaPlayer::paint(GraphicsContext* p, const IntRect& r)
752 {
753     m_private->paint(p, r);
754 }
755
756 void MediaPlayer::paintCurrentFrameInContext(GraphicsContext* p, const IntRect& r)
757 {
758     m_private->paintCurrentFrameInContext(p, r);
759 }
760
761 bool MediaPlayer::copyVideoTextureToPlatformTexture(GraphicsContext3D* context, Platform3DObject texture, GC3Dint level, GC3Denum type, GC3Denum internalFormat, bool premultiplyAlpha, bool flipY)
762 {
763     return m_private->copyVideoTextureToPlatformTexture(context, texture, level, type, internalFormat, premultiplyAlpha, flipY);
764 }
765
766 PassNativeImagePtr MediaPlayer::nativeImageForCurrentTime()
767 {
768     return m_private->nativeImageForCurrentTime();
769 }
770
771 MediaPlayer::SupportsType MediaPlayer::supportsType(const MediaEngineSupportParameters& parameters, const MediaPlayerSupportsTypeClient* client)
772 {
773     // 4.8.10.3 MIME types - The canPlayType(type) method must return the empty string if type is a type that the 
774     // user agent knows it cannot render or is the type "application/octet-stream"
775     if (parameters.type == applicationOctetStream())
776         return IsNotSupported;
777
778     MediaPlayerFactory* engine = bestMediaEngineForSupportParameters(parameters);
779     if (!engine)
780         return IsNotSupported;
781
782 #if PLATFORM(COCOA)
783     // YouTube will ask if the HTMLMediaElement canPlayType video/webm, then
784     // video/x-flv, then finally video/mp4, and will then load a URL of the first type
785     // in that list which returns "probably". When Perian is installed,
786     // MediaPlayerPrivateQTKit claims to support both video/webm and video/x-flv, but
787     // due to a bug in Perian, loading media in these formats will sometimes fail on
788     // slow connections. <https://bugs.webkit.org/show_bug.cgi?id=86409>
789     if (client && client->mediaPlayerNeedsSiteSpecificHacks()) {
790         String host = client->mediaPlayerDocumentHost();
791         if ((host.endsWith(".youtube.com", false) || equalIgnoringCase("youtube.com", host))
792             && (parameters.type.startsWith("video/webm", false) || parameters.type.startsWith("video/x-flv", false)))
793             return IsNotSupported;
794     }
795 #else
796     UNUSED_PARAM(client);
797 #endif
798
799     return engine->supportsTypeAndCodecs(parameters);
800 }
801
802 void MediaPlayer::getSupportedTypes(HashSet<String>& types)
803 {
804     Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
805     if (engines.isEmpty())
806         return;
807
808     unsigned count = engines.size();
809     for (unsigned ndx = 0; ndx < count; ndx++)
810         engines[ndx]->getSupportedTypes(types);
811
812
813 bool MediaPlayer::isAvailable()
814 {
815     return !installedMediaEngines().isEmpty();
816
817
818 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
819 void MediaPlayer::deliverNotification(MediaPlayerProxyNotificationType notification)
820 {
821     m_private->deliverNotification(notification);
822 }
823
824 void MediaPlayer::setMediaPlayerProxy(WebMediaPlayerProxy* proxy)
825 {
826     m_playerProxy = proxy;
827     m_private->setMediaPlayerProxy(proxy);
828 }
829
830 void MediaPlayer::setControls(bool controls)
831 {
832     m_private->setControls(controls);
833 }
834 #endif
835
836 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) || USE(NATIVE_FULLSCREEN_VIDEO)
837 void MediaPlayer::enterFullscreen()
838 {
839     m_private->enterFullscreen();
840 }
841
842 void MediaPlayer::exitFullscreen()
843 {
844     m_private->exitFullscreen();
845 }
846 #endif
847
848 #if ENABLE(IOS_AIRPLAY)
849 bool MediaPlayer::isCurrentPlaybackTargetWireless() const
850 {
851     return m_private->isCurrentPlaybackTargetWireless();
852 }
853
854 void MediaPlayer::showPlaybackTargetPicker()
855 {
856     m_private->showPlaybackTargetPicker();
857 }
858
859 bool MediaPlayer::hasWirelessPlaybackTargets() const
860 {
861     return m_private->hasWirelessPlaybackTargets();
862 }
863
864 bool MediaPlayer::wirelessVideoPlaybackDisabled() const
865 {
866     return m_private->wirelessVideoPlaybackDisabled();
867 }
868
869 void MediaPlayer::setWirelessVideoPlaybackDisabled(bool disabled)
870 {
871     m_private->setWirelessVideoPlaybackDisabled(disabled);
872 }
873
874 void MediaPlayer::setHasPlaybackTargetAvailabilityListeners(bool hasListeners)
875 {
876     m_private->setHasPlaybackTargetAvailabilityListeners(hasListeners);
877 }
878
879 void MediaPlayer::currentPlaybackTargetIsWirelessChanged()
880 {
881     if (m_mediaPlayerClient)
882         m_mediaPlayerClient->mediaPlayerCurrentPlaybackTargetIsWirelessChanged(this);
883 }
884
885 void MediaPlayer::playbackTargetAvailabilityChanged()
886 {
887     if (m_mediaPlayerClient)
888         m_mediaPlayerClient->mediaPlayerPlaybackTargetAvailabilityChanged(this);
889 }
890 #endif
891
892 #if USE(NATIVE_FULLSCREEN_VIDEO)
893 bool MediaPlayer::canEnterFullscreen() const
894 {
895     return m_private->canEnterFullscreen();
896 }
897 #endif
898
899 void MediaPlayer::acceleratedRenderingStateChanged()
900 {
901     m_private->acceleratedRenderingStateChanged();
902 }
903
904 bool MediaPlayer::supportsAcceleratedRendering() const
905 {
906     return m_private->supportsAcceleratedRendering();
907 }
908
909 bool MediaPlayer::shouldMaintainAspectRatio() const
910 {
911     return m_private->shouldMaintainAspectRatio();
912 }
913
914 void MediaPlayer::setShouldMaintainAspectRatio(bool maintainAspectRatio)
915 {
916     m_private->setShouldMaintainAspectRatio(maintainAspectRatio);
917 }
918
919 bool MediaPlayer::hasSingleSecurityOrigin() const
920 {
921     return m_private->hasSingleSecurityOrigin();
922 }
923
924 bool MediaPlayer::didPassCORSAccessCheck() const
925 {
926     return m_private->didPassCORSAccessCheck();
927 }
928
929 MediaPlayer::MovieLoadType MediaPlayer::movieLoadType() const
930 {
931     return m_private->movieLoadType();
932 }
933
934 double MediaPlayer::mediaTimeForTimeValue(double timeValue) const
935 {
936     return m_private->mediaTimeForTimeValueDouble(timeValue);
937 }
938
939 double MediaPlayer::maximumDurationToCacheMediaTime() const
940 {
941     return m_private->maximumDurationToCacheMediaTime();
942 }
943
944 unsigned MediaPlayer::decodedFrameCount() const
945 {
946     return m_private->decodedFrameCount();
947 }
948
949 unsigned MediaPlayer::droppedFrameCount() const
950 {
951     return m_private->droppedFrameCount();
952 }
953
954 unsigned MediaPlayer::audioDecodedByteCount() const
955 {
956     return m_private->audioDecodedByteCount();
957 }
958
959 unsigned MediaPlayer::videoDecodedByteCount() const
960 {
961     return m_private->videoDecodedByteCount();
962 }
963
964 void MediaPlayer::reloadTimerFired(Timer<MediaPlayer>&)
965 {
966     m_private->cancelLoad();
967     loadWithNextMediaEngine(m_currentMediaEngine);
968 }
969
970 void MediaPlayer::getSitesInMediaCache(Vector<String>& sites)
971 {
972     Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
973     unsigned size = engines.size();
974     for (unsigned i = 0; i < size; i++) {
975         if (!engines[i]->getSitesInMediaCache)
976             continue;
977         Vector<String> engineSites;
978         engines[i]->getSitesInMediaCache(engineSites);
979         sites.appendVector(engineSites);
980     }
981 }
982
983 void MediaPlayer::clearMediaCache()
984 {
985     Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
986     unsigned size = engines.size();
987     for (unsigned i = 0; i < size; i++) {
988         if (engines[i]->clearMediaCache)
989             engines[i]->clearMediaCache();
990     }
991 }
992
993 void MediaPlayer::clearMediaCacheForSite(const String& site)
994 {
995     Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
996     unsigned size = engines.size();
997     for (unsigned i = 0; i < size; i++) {
998         if (engines[i]->clearMediaCacheForSite)
999             engines[i]->clearMediaCacheForSite(site);
1000     }
1001 }
1002
1003 bool MediaPlayer::supportsKeySystem(const String& keySystem, const String& mimeType)
1004 {
1005     for (auto& engine : installedMediaEngines()) {
1006         if (engine->supportsKeySystem && engine->supportsKeySystem(keySystem, mimeType))
1007             return true;
1008     }
1009     return false;
1010 }
1011
1012 void MediaPlayer::setPrivateBrowsingMode(bool privateBrowsingMode)
1013 {
1014     m_privateBrowsing = privateBrowsingMode;
1015     m_private->setPrivateBrowsingMode(m_privateBrowsing);
1016 }
1017
1018 #if PLATFORM(IOS)
1019 void MediaPlayer::attributeChanged(const String& name, const String& value) 
1020 {
1021     m_private->attributeChanged(name, value);
1022 }
1023
1024 bool MediaPlayer::readyForPlayback() const
1025 {
1026     return m_private->readyForPlayback();
1027 }
1028 #endif
1029
1030 // Client callbacks.
1031 void MediaPlayer::networkStateChanged()
1032 {
1033     // If more than one media engine is installed and this one failed before finding metadata,
1034     // let the next engine try.
1035     if (m_private->networkState() >= FormatError
1036         && m_private->readyState() < HaveMetadata
1037         && installedMediaEngines().size() > 1) {
1038         if (m_contentMIMEType.isEmpty() || nextBestMediaEngine(m_currentMediaEngine)) {
1039             m_reloadTimer.startOneShot(0);
1040             return;
1041         }
1042     }
1043     if (m_mediaPlayerClient)
1044         m_mediaPlayerClient->mediaPlayerNetworkStateChanged(this);
1045 }
1046
1047 void MediaPlayer::readyStateChanged()
1048 {
1049     if (m_mediaPlayerClient)
1050         m_mediaPlayerClient->mediaPlayerReadyStateChanged(this);
1051 }
1052
1053 void MediaPlayer::volumeChanged(double newVolume)
1054 {
1055 #if PLATFORM(IOS)
1056     UNUSED_PARAM(newVolume);
1057     m_volume = m_private->volume();
1058 #else
1059     m_volume = newVolume;
1060 #endif
1061     if (m_mediaPlayerClient)
1062         m_mediaPlayerClient->mediaPlayerVolumeChanged(this);
1063 }
1064
1065 void MediaPlayer::muteChanged(bool newMuted)
1066 {
1067     m_muted = newMuted;
1068     if (m_mediaPlayerClient)
1069         m_mediaPlayerClient->mediaPlayerMuteChanged(this);
1070 }
1071
1072 void MediaPlayer::timeChanged()
1073 {
1074     if (m_mediaPlayerClient)
1075         m_mediaPlayerClient->mediaPlayerTimeChanged(this);
1076 }
1077
1078 void MediaPlayer::sizeChanged()
1079 {
1080     if (m_mediaPlayerClient)
1081         m_mediaPlayerClient->mediaPlayerSizeChanged(this);
1082 }
1083
1084 void MediaPlayer::repaint()
1085 {
1086     if (m_mediaPlayerClient)
1087         m_mediaPlayerClient->mediaPlayerRepaint(this);
1088 }
1089
1090 void MediaPlayer::durationChanged()
1091 {
1092     if (m_mediaPlayerClient)
1093         m_mediaPlayerClient->mediaPlayerDurationChanged(this);
1094 }
1095
1096 void MediaPlayer::rateChanged()
1097 {
1098     if (m_mediaPlayerClient)
1099         m_mediaPlayerClient->mediaPlayerRateChanged(this);
1100 }
1101
1102 void MediaPlayer::playbackStateChanged()
1103 {
1104     if (m_mediaPlayerClient)
1105         m_mediaPlayerClient->mediaPlayerPlaybackStateChanged(this);
1106 }
1107
1108 void MediaPlayer::firstVideoFrameAvailable()
1109 {
1110     if (m_mediaPlayerClient)
1111         m_mediaPlayerClient->mediaPlayerFirstVideoFrameAvailable(this);
1112 }
1113
1114 void MediaPlayer::characteristicChanged()
1115 {
1116     if (m_mediaPlayerClient)
1117         m_mediaPlayerClient->mediaPlayerCharacteristicChanged(this);
1118 }
1119
1120 #if ENABLE(WEB_AUDIO)
1121 AudioSourceProvider* MediaPlayer::audioSourceProvider()
1122 {
1123     return m_private->audioSourceProvider();
1124 }
1125 #endif // WEB_AUDIO
1126
1127 #if ENABLE(ENCRYPTED_MEDIA)
1128 void MediaPlayer::keyAdded(const String& keySystem, const String& sessionId)
1129 {
1130     if (m_mediaPlayerClient)
1131         m_mediaPlayerClient->mediaPlayerKeyAdded(this, keySystem, sessionId);
1132 }
1133
1134 void MediaPlayer::keyError(const String& keySystem, const String& sessionId, MediaPlayerClient::MediaKeyErrorCode errorCode, unsigned short systemCode)
1135 {
1136     if (m_mediaPlayerClient)
1137         m_mediaPlayerClient->mediaPlayerKeyError(this, keySystem, sessionId, errorCode, systemCode);
1138 }
1139
1140 void MediaPlayer::keyMessage(const String& keySystem, const String& sessionId, const unsigned char* message, unsigned messageLength, const URL& defaultURL)
1141 {
1142     if (m_mediaPlayerClient)
1143         m_mediaPlayerClient->mediaPlayerKeyMessage(this, keySystem, sessionId, message, messageLength, defaultURL);
1144 }
1145
1146 bool MediaPlayer::keyNeeded(const String& keySystem, const String& sessionId, const unsigned char* initData, unsigned initDataLength)
1147 {
1148     if (m_mediaPlayerClient)
1149         return m_mediaPlayerClient->mediaPlayerKeyNeeded(this, keySystem, sessionId, initData, initDataLength);
1150     return false;
1151 }
1152 #endif
1153
1154 #if ENABLE(ENCRYPTED_MEDIA_V2)
1155 bool MediaPlayer::keyNeeded(Uint8Array* initData)
1156 {
1157     if (m_mediaPlayerClient)
1158         return m_mediaPlayerClient->mediaPlayerKeyNeeded(this, initData);
1159     return false;
1160 }
1161 #endif
1162
1163 String MediaPlayer::referrer() const
1164 {
1165     if (!m_mediaPlayerClient)
1166         return String();
1167
1168     return m_mediaPlayerClient->mediaPlayerReferrer();
1169 }
1170
1171 String MediaPlayer::userAgent() const
1172 {
1173     if (!m_mediaPlayerClient)
1174         return String();
1175     
1176     return m_mediaPlayerClient->mediaPlayerUserAgent();
1177 }
1178
1179 String MediaPlayer::engineDescription() const
1180 {
1181     if (!m_private)
1182         return String();
1183
1184     return m_private->engineDescription();
1185 }
1186
1187 #if PLATFORM(WIN) && USE(AVFOUNDATION)
1188 GraphicsDeviceAdapter* MediaPlayer::graphicsDeviceAdapter() const
1189 {
1190     if (!m_mediaPlayerClient)
1191         return 0;
1192     
1193     return m_mediaPlayerClient->mediaPlayerGraphicsDeviceAdapter(this);
1194 }
1195 #endif
1196
1197 CachedResourceLoader* MediaPlayer::cachedResourceLoader()
1198 {
1199     if (!m_mediaPlayerClient)
1200         return 0;
1201
1202     return m_mediaPlayerClient->mediaPlayerCachedResourceLoader();
1203 }
1204
1205 #if ENABLE(VIDEO_TRACK)
1206 void MediaPlayer::addAudioTrack(PassRefPtr<AudioTrackPrivate> track)
1207 {
1208     if (!m_mediaPlayerClient)
1209         return;
1210
1211     m_mediaPlayerClient->mediaPlayerDidAddAudioTrack(track);
1212 }
1213
1214 void MediaPlayer::removeAudioTrack(PassRefPtr<AudioTrackPrivate> track)
1215 {
1216     if (!m_mediaPlayerClient)
1217         return;
1218
1219     m_mediaPlayerClient->mediaPlayerDidRemoveAudioTrack(track);
1220 }
1221
1222 void MediaPlayer::addTextTrack(PassRefPtr<InbandTextTrackPrivate> track)
1223 {
1224     if (!m_mediaPlayerClient)
1225         return;
1226
1227     m_mediaPlayerClient->mediaPlayerDidAddTextTrack(track);
1228 }
1229
1230 void MediaPlayer::removeTextTrack(PassRefPtr<InbandTextTrackPrivate> track)
1231 {
1232     if (!m_mediaPlayerClient)
1233         return;
1234
1235     m_mediaPlayerClient->mediaPlayerDidRemoveTextTrack(track);
1236 }
1237
1238 void MediaPlayer::addVideoTrack(PassRefPtr<VideoTrackPrivate> track)
1239 {
1240     if (!m_mediaPlayerClient)
1241         return;
1242
1243     m_mediaPlayerClient->mediaPlayerDidAddVideoTrack(track);
1244 }
1245
1246 void MediaPlayer::removeVideoTrack(PassRefPtr<VideoTrackPrivate> track)
1247 {
1248     if (!m_mediaPlayerClient)
1249         return;
1250
1251     m_mediaPlayerClient->mediaPlayerDidRemoveVideoTrack(track);
1252 }
1253
1254 bool MediaPlayer::requiresTextTrackRepresentation() const
1255 {
1256     return m_private->requiresTextTrackRepresentation();
1257 }
1258
1259 void MediaPlayer::setTextTrackRepresentation(TextTrackRepresentation* representation)
1260 {
1261     m_private->setTextTrackRepresentation(representation);
1262 }
1263
1264 #if ENABLE(AVF_CAPTIONS)
1265 Vector<RefPtr<PlatformTextTrack>> MediaPlayer::outOfBandTrackSources()
1266 {
1267     if (!m_mediaPlayerClient)
1268         return Vector<RefPtr<PlatformTextTrack>> ();
1269     
1270     return m_mediaPlayerClient->outOfBandTrackSources();
1271 }
1272 #endif
1273
1274 #endif // ENABLE(VIDEO_TRACK)
1275
1276 #if USE(PLATFORM_TEXT_TRACK_MENU)
1277 bool MediaPlayer::implementsTextTrackControls() const
1278 {
1279     return m_private->implementsTextTrackControls();
1280 }
1281
1282 PassRefPtr<PlatformTextTrackMenuInterface> MediaPlayer::textTrackMenu()
1283 {
1284     return m_private->textTrackMenu();
1285 }
1286 #endif // USE(PLATFORM_TEXT_TRACK_MENU)
1287
1288 void MediaPlayer::resetMediaEngines()
1289 {
1290     installedMediaEngines(ResetEngines);
1291 }
1292
1293 #if USE(GSTREAMER)
1294 void MediaPlayer::simulateAudioInterruption()
1295 {
1296     if (!m_private)
1297         return;
1298
1299     m_private->simulateAudioInterruption();
1300 }
1301 #endif
1302
1303 String MediaPlayer::languageOfPrimaryAudioTrack() const
1304 {
1305     if (!m_private)
1306         return emptyString();
1307     
1308     return m_private->languageOfPrimaryAudioTrack();
1309 }
1310
1311 size_t MediaPlayer::extraMemoryCost() const
1312 {
1313     if (!m_private)
1314         return 0;
1315
1316     return m_private->extraMemoryCost();
1317 }
1318
1319 unsigned long long MediaPlayer::fileSize() const
1320 {
1321     if (!m_private)
1322         return 0;
1323     
1324     return m_private->fileSize();
1325 }
1326
1327 #if ENABLE(MEDIA_SOURCE)
1328 unsigned long MediaPlayer::totalVideoFrames()
1329 {
1330     if (!m_private)
1331         return 0;
1332
1333     return m_private->totalVideoFrames();
1334 }
1335
1336 unsigned long MediaPlayer::droppedVideoFrames()
1337 {
1338     if (!m_private)
1339         return 0;
1340
1341     return m_private->droppedVideoFrames();
1342 }
1343
1344 unsigned long MediaPlayer::corruptedVideoFrames()
1345 {
1346     if (!m_private)
1347         return 0;
1348
1349     return m_private->corruptedVideoFrames();
1350 }
1351
1352 double MediaPlayer::totalFrameDelay()
1353 {
1354     if (!m_private)
1355         return 0;
1356
1357     return m_private->totalFrameDelay();
1358 }
1359 #endif
1360
1361 bool MediaPlayer::shouldWaitForResponseToAuthenticationChallenge(const AuthenticationChallenge& challenge)
1362 {
1363     if (!m_mediaPlayerClient)
1364         return false;
1365
1366     return m_mediaPlayerClient->mediaPlayerShouldWaitForResponseToAuthenticationChallenge(challenge);
1367 }
1368
1369 void MediaPlayerFactorySupport::callRegisterMediaEngine(MediaEngineRegister registerMediaEngine)
1370 {
1371     registerMediaEngine(addMediaEngine);
1372 }
1373
1374 }
1375
1376 #endif