1 /* 2 * Copyright (C) 2007, 2008, 2009, 2010 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 #include "MediaPlayerPrivate.h" 31 32 #include "ContentType.h" 33 #include "IntRect.h" 34 #include "MIMETypeRegistry.h" 35 #include "FrameView.h" 36 #include "Frame.h" 37 #include "Document.h" 38 #include "TimeRanges.h" 39 40 #if PLATFORM(MAC) 41 #include "MediaPlayerPrivateQTKit.h" 42 #elif OS(WINCE) && !PLATFORM(QT) 43 #include "MediaPlayerPrivateWince.h" 44 #elif PLATFORM(WIN) 45 #include "MediaPlayerPrivateQuickTimeWin.h" 46 #elif PLATFORM(GTK) 47 #include "MediaPlayerPrivateGStreamer.h" 48 #elif PLATFORM(QT) 49 #include "MediaPlayerPrivatePhonon.h" 50 #elif PLATFORM(CHROMIUM) 51 #include "MediaPlayerPrivateChromium.h" 52 #elif PLATFORM(ANDROID) 53 #include "MediaPlayerPrivateAndroid.h" 54 #endif 55 56 namespace WebCore { 57 58 // a null player to make MediaPlayer logic simpler 59 60 class NullMediaPlayerPrivate : public MediaPlayerPrivateInterface { 61 public: 62 NullMediaPlayerPrivate(MediaPlayer*) { } 63 64 virtual void load(const String&) { } 65 virtual void cancelLoad() { } 66 67 virtual void prepareToPlay() { } 68 virtual void play() { } 69 virtual void pause() { } 70 71 virtual PlatformMedia platformMedia() const { return NoPlatformMedia; } 72 73 virtual IntSize naturalSize() const { return IntSize(0, 0); } 74 75 virtual bool hasVideo() const { return false; } 76 virtual bool hasAudio() const { return false; } 77 78 virtual void setVisible(bool) { } 79 80 virtual float duration() const { return 0; } 81 82 virtual float currentTime() const { return 0; } 83 virtual void seek(float) { } 84 virtual bool seeking() const { return false; } 85 86 virtual void setRate(float) { } 87 virtual void setPreservesPitch(bool) { } 88 virtual bool paused() const { return false; } 89 90 virtual void setVolume(float) { } 91 92 virtual bool supportsMuting() const { return false; } 93 virtual void setMuted(bool) { } 94 95 virtual bool hasClosedCaptions() const { return false; } 96 virtual void setClosedCaptionsVisible(bool) { }; 97 98 virtual MediaPlayer::NetworkState networkState() const { return MediaPlayer::Empty; } 99 virtual MediaPlayer::ReadyState readyState() const { return MediaPlayer::HaveNothing; } 100 101 virtual float maxTimeSeekable() const { return 0; } 102 virtual PassRefPtr<TimeRanges> buffered() const { return TimeRanges::create(); } 103 104 virtual unsigned totalBytes() const { return 0; } 105 virtual unsigned bytesLoaded() const { return 0; } 106 107 virtual void setSize(const IntSize&) { } 108 109 virtual void paint(GraphicsContext*, const IntRect&) { } 110 111 virtual bool canLoadPoster() const { return false; } 112 virtual void setPoster(const String&) { } 113 114 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) 115 virtual void deliverNotification(MediaPlayerProxyNotificationType) { } 116 virtual void setMediaPlayerProxy(WebMediaPlayerProxy*) { } 117 #endif 118 119 virtual bool hasSingleSecurityOrigin() const { return true; } 120 }; 121 122 static MediaPlayerPrivateInterface* createNullMediaPlayer(MediaPlayer* player) 123 { 124 return new NullMediaPlayerPrivate(player); 125 } 126 127 128 // engine support 129 130 struct MediaPlayerFactory : Noncopyable { 131 MediaPlayerFactory(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsTypeAndCodecs) 132 : constructor(constructor) 133 , getSupportedTypes(getSupportedTypes) 134 , supportsTypeAndCodecs(supportsTypeAndCodecs) 135 { 136 } 137 138 CreateMediaEnginePlayer constructor; 139 MediaEngineSupportedTypes getSupportedTypes; 140 MediaEngineSupportsType supportsTypeAndCodecs; 141 }; 142 143 static void addMediaEngine(CreateMediaEnginePlayer, MediaEngineSupportedTypes, MediaEngineSupportsType); 144 static MediaPlayerFactory* chooseBestEngineForTypeAndCodecs(const String& type, const String& codecs); 145 146 static Vector<MediaPlayerFactory*>& installedMediaEngines() 147 { 148 DEFINE_STATIC_LOCAL(Vector<MediaPlayerFactory*>, installedEngines, ()); 149 static bool enginesQueried = false; 150 151 if (!enginesQueried) { 152 enginesQueried = true; 153 MediaPlayerPrivate::registerMediaEngine(addMediaEngine); 154 155 // register additional engines here 156 } 157 158 return installedEngines; 159 } 160 161 static void addMediaEngine(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsType) 162 { 163 ASSERT(constructor); 164 ASSERT(getSupportedTypes); 165 ASSERT(supportsType); 166 installedMediaEngines().append(new MediaPlayerFactory(constructor, getSupportedTypes, supportsType)); 167 } 168 169 static MediaPlayerFactory* chooseBestEngineForTypeAndCodecs(const String& type, const String& codecs) 170 { 171 Vector<MediaPlayerFactory*>& engines = installedMediaEngines(); 172 173 if (engines.isEmpty()) 174 return 0; 175 176 MediaPlayerFactory* engine = 0; 177 MediaPlayer::SupportsType supported = MediaPlayer::IsNotSupported; 178 179 unsigned count = engines.size(); 180 for (unsigned ndx = 0; ndx < count; ndx++) { 181 MediaPlayer::SupportsType engineSupport = engines[ndx]->supportsTypeAndCodecs(type, codecs); 182 if (engineSupport > supported) { 183 supported = engineSupport; 184 engine = engines[ndx]; 185 } 186 } 187 188 return engine; 189 } 190 191 // media player 192 193 MediaPlayer::MediaPlayer(MediaPlayerClient* client) 194 : m_mediaPlayerClient(client) 195 , m_private(createNullMediaPlayer(this)) 196 , m_currentMediaEngine(0) 197 , m_frameView(0) 198 , m_visible(false) 199 , m_rate(1.0f) 200 , m_volume(1.0f) 201 , m_muted(false) 202 , m_preservesPitch(true) 203 , m_autobuffer(false) 204 #if PLATFORM(ANDROID) 205 , m_mediaElementType(Video) 206 #endif 207 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) 208 , m_playerProxy(0) 209 #endif 210 { 211 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) 212 Vector<MediaPlayerFactory*>& engines = installedMediaEngines(); 213 if (!engines.isEmpty()) { 214 m_currentMediaEngine = engines[0]; 215 m_private.clear(); 216 m_private.set(engines[0]->constructor(this)); 217 } 218 #endif 219 } 220 221 MediaPlayer::~MediaPlayer() 222 { 223 } 224 225 void MediaPlayer::load(const String& url, const ContentType& contentType) 226 { 227 String type = contentType.type(); 228 String codecs = contentType.parameter("codecs"); 229 230 // if we don't know the MIME type, see if the extension can help 231 if (type.isEmpty() || type == "application/octet-stream" || type == "text/plain") { 232 int pos = url.reverseFind('.'); 233 if (pos >= 0) { 234 String extension = url.substring(pos + 1); 235 String mediaType = MIMETypeRegistry::getMediaMIMETypeForExtension(extension); 236 if (!mediaType.isEmpty()) 237 type = mediaType; 238 } 239 } 240 241 MediaPlayerFactory* engine = 0; 242 if (!type.isEmpty()) 243 engine = chooseBestEngineForTypeAndCodecs(type, codecs); 244 245 // if we didn't find an engine that claims the MIME type, just use the first engine 246 if (!engine && !installedMediaEngines().isEmpty()) 247 engine = installedMediaEngines()[0]; 248 249 // don't delete and recreate the player unless it comes from a different engine 250 if (engine && m_currentMediaEngine != engine) { 251 m_currentMediaEngine = engine; 252 m_private.clear(); 253 m_private.set(engine->constructor(this)); 254 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) 255 m_private->setMediaPlayerProxy(m_playerProxy); 256 #endif 257 m_private->setAutobuffer(autobuffer()); 258 m_private->setPreservesPitch(preservesPitch()); 259 } 260 261 if (m_private) 262 m_private->load(url); 263 else 264 m_private.set(createNullMediaPlayer(this)); 265 } 266 267 bool MediaPlayer::hasAvailableVideoFrame() const 268 { 269 return m_private->hasAvailableVideoFrame(); 270 } 271 272 bool MediaPlayer::canLoadPoster() const 273 { 274 return m_private->canLoadPoster(); 275 } 276 277 void MediaPlayer::setPoster(const String& url) 278 { 279 m_private->setPoster(url); 280 } 281 282 void MediaPlayer::cancelLoad() 283 { 284 m_private->cancelLoad(); 285 } 286 287 void MediaPlayer::prepareToPlay() 288 { 289 m_private->prepareToPlay(); 290 } 291 292 void MediaPlayer::play() 293 { 294 m_private->play(); 295 } 296 297 void MediaPlayer::pause() 298 { 299 m_private->pause(); 300 } 301 302 float MediaPlayer::duration() const 303 { 304 return m_private->duration(); 305 } 306 307 float MediaPlayer::startTime() const 308 { 309 return m_private->startTime(); 310 } 311 312 float MediaPlayer::currentTime() const 313 { 314 return m_private->currentTime(); 315 } 316 317 void MediaPlayer::seek(float time) 318 { 319 m_private->seek(time); 320 } 321 322 bool MediaPlayer::paused() const 323 { 324 return m_private->paused(); 325 } 326 327 bool MediaPlayer::seeking() const 328 { 329 return m_private->seeking(); 330 } 331 332 bool MediaPlayer::supportsFullscreen() const 333 { 334 return m_private->supportsFullscreen(); 335 } 336 337 bool MediaPlayer::supportsSave() const 338 { 339 return m_private->supportsSave(); 340 } 341 342 IntSize MediaPlayer::naturalSize() 343 { 344 return m_private->naturalSize(); 345 } 346 347 bool MediaPlayer::hasVideo() const 348 { 349 return m_private->hasVideo(); 350 } 351 352 bool MediaPlayer::hasAudio() const 353 { 354 return m_private->hasAudio(); 355 } 356 357 bool MediaPlayer::inMediaDocument() 358 { 359 Frame* frame = m_frameView ? m_frameView->frame() : 0; 360 Document* document = frame ? frame->document() : 0; 361 362 return document && document->isMediaDocument(); 363 } 364 365 PlatformMedia MediaPlayer::platformMedia() const 366 { 367 return m_private->platformMedia(); 368 } 369 370 MediaPlayer::NetworkState MediaPlayer::networkState() 371 { 372 return m_private->networkState(); 373 } 374 375 MediaPlayer::ReadyState MediaPlayer::readyState() 376 { 377 return m_private->readyState(); 378 } 379 380 float MediaPlayer::volume() const 381 { 382 return m_volume; 383 } 384 385 void MediaPlayer::setVolume(float volume) 386 { 387 m_volume = volume; 388 m_private->setVolume(volume); 389 } 390 391 bool MediaPlayer::muted() const 392 { 393 return m_muted; 394 } 395 396 bool MediaPlayer::supportsMuting() const 397 { 398 return m_private->supportsMuting(); 399 } 400 401 void MediaPlayer::setMuted(bool muted) 402 { 403 m_muted = muted; 404 m_private->setMuted(muted); 405 } 406 407 bool MediaPlayer::hasClosedCaptions() const 408 { 409 return m_private->hasClosedCaptions(); 410 } 411 412 void MediaPlayer::setClosedCaptionsVisible(bool closedCaptionsVisible) 413 { 414 m_private->setClosedCaptionsVisible(closedCaptionsVisible); 415 } 416 417 float MediaPlayer::rate() const 418 { 419 return m_rate; 420 } 421 422 void MediaPlayer::setRate(float rate) 423 { 424 m_rate = rate; 425 m_private->setRate(rate); 426 } 427 428 bool MediaPlayer::preservesPitch() const 429 { 430 return m_preservesPitch; 431 } 432 433 void MediaPlayer::setPreservesPitch(bool preservesPitch) 434 { 435 m_preservesPitch = preservesPitch; 436 m_private->setPreservesPitch(preservesPitch); 437 } 438 439 PassRefPtr<TimeRanges> MediaPlayer::buffered() 440 { 441 return m_private->buffered(); 442 } 443 444 float MediaPlayer::maxTimeSeekable() 445 { 446 return m_private->maxTimeSeekable(); 447 } 448 449 unsigned MediaPlayer::bytesLoaded() 450 { 451 return m_private->bytesLoaded(); 452 } 453 454 void MediaPlayer::setSize(const IntSize& size) 455 { 456 m_size = size; 457 m_private->setSize(size); 458 } 459 460 bool MediaPlayer::visible() const 461 { 462 return m_visible; 463 } 464 465 void MediaPlayer::setVisible(bool b) 466 { 467 m_visible = b; 468 m_private->setVisible(b); 469 } 470 471 bool MediaPlayer::autobuffer() const 472 { 473 return m_autobuffer; 474 } 475 476 void MediaPlayer::setAutobuffer(bool b) 477 { 478 if (m_autobuffer != b) { 479 m_autobuffer = b; 480 m_private->setAutobuffer(b); 481 } 482 } 483 484 void MediaPlayer::paint(GraphicsContext* p, const IntRect& r) 485 { 486 m_private->paint(p, r); 487 } 488 489 void MediaPlayer::paintCurrentFrameInContext(GraphicsContext* p, const IntRect& r) 490 { 491 m_private->paintCurrentFrameInContext(p, r); 492 } 493 494 MediaPlayer::SupportsType MediaPlayer::supportsType(ContentType contentType) 495 { 496 String type = contentType.type(); 497 String codecs = contentType.parameter("codecs"); 498 MediaPlayerFactory* engine = chooseBestEngineForTypeAndCodecs(type, codecs); 499 500 if (!engine) 501 return IsNotSupported; 502 503 return engine->supportsTypeAndCodecs(type, codecs); 504 } 505 506 void MediaPlayer::getSupportedTypes(HashSet<String>& types) 507 { 508 Vector<MediaPlayerFactory*>& engines = installedMediaEngines(); 509 if (engines.isEmpty()) 510 return; 511 512 unsigned count = engines.size(); 513 for (unsigned ndx = 0; ndx < count; ndx++) 514 engines[ndx]->getSupportedTypes(types); 515 } 516 517 bool MediaPlayer::isAvailable() 518 { 519 return !installedMediaEngines().isEmpty(); 520 } 521 522 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) 523 void MediaPlayer::deliverNotification(MediaPlayerProxyNotificationType notification) 524 { 525 m_private->deliverNotification(notification); 526 } 527 528 void MediaPlayer::setMediaPlayerProxy(WebMediaPlayerProxy* proxy) 529 { 530 m_playerProxy = proxy; 531 m_private->setMediaPlayerProxy(proxy); 532 } 533 #endif 534 535 #if USE(ACCELERATED_COMPOSITING) 536 void MediaPlayer::acceleratedRenderingStateChanged() 537 { 538 m_private->acceleratedRenderingStateChanged(); 539 } 540 541 bool MediaPlayer::supportsAcceleratedRendering() const 542 { 543 return m_private->supportsAcceleratedRendering(); 544 } 545 #endif // USE(ACCELERATED_COMPOSITING) 546 547 bool MediaPlayer::hasSingleSecurityOrigin() const 548 { 549 return m_private->hasSingleSecurityOrigin(); 550 } 551 552 MediaPlayer::MovieLoadType MediaPlayer::movieLoadType() const 553 { 554 return m_private->movieLoadType(); 555 } 556 557 // Client callbacks. 558 void MediaPlayer::networkStateChanged() 559 { 560 if (m_mediaPlayerClient) 561 m_mediaPlayerClient->mediaPlayerNetworkStateChanged(this); 562 } 563 564 void MediaPlayer::readyStateChanged() 565 { 566 if (m_mediaPlayerClient) 567 m_mediaPlayerClient->mediaPlayerReadyStateChanged(this); 568 } 569 570 void MediaPlayer::volumeChanged(float newVolume) 571 { 572 m_volume = newVolume; 573 if (m_mediaPlayerClient) 574 m_mediaPlayerClient->mediaPlayerVolumeChanged(this); 575 } 576 577 void MediaPlayer::muteChanged(bool newMuted) 578 { 579 m_muted = newMuted; 580 if (m_mediaPlayerClient) 581 m_mediaPlayerClient->mediaPlayerMuteChanged(this); 582 } 583 584 void MediaPlayer::timeChanged() 585 { 586 if (m_mediaPlayerClient) 587 m_mediaPlayerClient->mediaPlayerTimeChanged(this); 588 } 589 590 void MediaPlayer::sizeChanged() 591 { 592 if (m_mediaPlayerClient) 593 m_mediaPlayerClient->mediaPlayerSizeChanged(this); 594 } 595 596 void MediaPlayer::repaint() 597 { 598 if (m_mediaPlayerClient) 599 m_mediaPlayerClient->mediaPlayerRepaint(this); 600 } 601 602 void MediaPlayer::durationChanged() 603 { 604 if (m_mediaPlayerClient) 605 m_mediaPlayerClient->mediaPlayerDurationChanged(this); 606 } 607 608 void MediaPlayer::rateChanged() 609 { 610 if (m_mediaPlayerClient) 611 m_mediaPlayerClient->mediaPlayerRateChanged(this); 612 } 613 614 } 615 616 #endif 617