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