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