1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "config.h" 6 #include "WebMediaPlayerClientImpl.h" 7 8 #if ENABLE(VIDEO) 9 10 #include "Frame.h" 11 #include "GraphicsContext.h" 12 #include "HTMLMediaElement.h" 13 #include "IntSize.h" 14 #include "KURL.h" 15 #include "MediaPlayer.h" 16 #include "NotImplemented.h" 17 #include "RenderView.h" 18 #include "TimeRanges.h" 19 #include "VideoLayerChromium.h" 20 21 #if USE(ACCELERATED_COMPOSITING) 22 #include "RenderLayerCompositor.h" 23 #endif 24 25 #include "VideoFrameChromium.h" 26 #include "VideoFrameChromiumImpl.h" 27 #include "WebCanvas.h" 28 #include "WebCString.h" 29 #include "WebFrameClient.h" 30 #include "WebFrameImpl.h" 31 #include "WebKit.h" 32 #include "WebKitClient.h" 33 #include "WebMediaElement.h" 34 #include "WebMediaPlayer.h" 35 #include "WebMimeRegistry.h" 36 #include "WebRect.h" 37 #include "WebSize.h" 38 #include "WebString.h" 39 #include "WebURL.h" 40 #include "WebViewImpl.h" 41 42 // WebCommon.h defines WEBKIT_USING_SKIA so this has to be included last. 43 #if WEBKIT_USING_SKIA 44 #include "PlatformContextSkia.h" 45 #endif 46 47 #include <wtf/Assertions.h> 48 #include <wtf/text/CString.h> 49 50 using namespace WebCore; 51 52 namespace WebKit { 53 54 static WebMediaPlayer* createWebMediaPlayer( 55 WebMediaPlayerClient* client, Frame* frame) 56 { 57 WebFrameImpl* webFrame = WebFrameImpl::fromFrame(frame); 58 59 if (!webFrame->client()) 60 return 0; 61 return webFrame->client()->createMediaPlayer(webFrame, client); 62 } 63 64 bool WebMediaPlayerClientImpl::m_isEnabled = false; 65 66 bool WebMediaPlayerClientImpl::isEnabled() 67 { 68 return m_isEnabled; 69 } 70 71 void WebMediaPlayerClientImpl::setIsEnabled(bool isEnabled) 72 { 73 m_isEnabled = isEnabled; 74 } 75 76 void WebMediaPlayerClientImpl::registerSelf(MediaEngineRegistrar registrar) 77 { 78 if (m_isEnabled) { 79 registrar(WebMediaPlayerClientImpl::create, 80 WebMediaPlayerClientImpl::getSupportedTypes, 81 WebMediaPlayerClientImpl::supportsType, 82 0, 83 0, 84 0); 85 } 86 } 87 88 WebMediaPlayerClientImpl* WebMediaPlayerClientImpl::fromMediaElement(const WebMediaElement* element) 89 { 90 PlatformMedia pm = element->constUnwrap<HTMLMediaElement>()->platformMedia(); 91 return static_cast<WebMediaPlayerClientImpl*>(pm.media.chromiumMediaPlayer); 92 } 93 94 WebMediaPlayer* WebMediaPlayerClientImpl::mediaPlayer() const 95 { 96 return m_webMediaPlayer.get(); 97 } 98 99 // WebMediaPlayerClient -------------------------------------------------------- 100 101 WebMediaPlayerClientImpl::~WebMediaPlayerClientImpl() 102 { 103 // VideoLayerChromium may outlive this object so make sure all frames are 104 // released. 105 #if USE(ACCELERATED_COMPOSITING) 106 if (m_videoLayer.get()) 107 m_videoLayer->releaseCurrentFrame(); 108 #endif 109 } 110 111 void WebMediaPlayerClientImpl::networkStateChanged() 112 { 113 ASSERT(m_mediaPlayer); 114 m_mediaPlayer->networkStateChanged(); 115 } 116 117 void WebMediaPlayerClientImpl::readyStateChanged() 118 { 119 ASSERT(m_mediaPlayer); 120 m_mediaPlayer->readyStateChanged(); 121 #if USE(ACCELERATED_COMPOSITING) 122 if (hasVideo() && supportsAcceleratedRendering() && !m_videoLayer.get()) 123 m_videoLayer = VideoLayerChromium::create(0, this); 124 #endif 125 } 126 127 void WebMediaPlayerClientImpl::volumeChanged(float newVolume) 128 { 129 ASSERT(m_mediaPlayer); 130 m_mediaPlayer->volumeChanged(newVolume); 131 } 132 133 void WebMediaPlayerClientImpl::muteChanged(bool newMute) 134 { 135 ASSERT(m_mediaPlayer); 136 m_mediaPlayer->muteChanged(newMute); 137 } 138 139 void WebMediaPlayerClientImpl::timeChanged() 140 { 141 ASSERT(m_mediaPlayer); 142 m_mediaPlayer->timeChanged(); 143 } 144 145 void WebMediaPlayerClientImpl::repaint() 146 { 147 ASSERT(m_mediaPlayer); 148 #if USE(ACCELERATED_COMPOSITING) 149 if (m_videoLayer.get() && supportsAcceleratedRendering()) 150 m_videoLayer->setNeedsDisplay(IntRect(0, 0, m_videoLayer->bounds().width(), m_videoLayer->bounds().height())); 151 #endif 152 m_mediaPlayer->repaint(); 153 } 154 155 void WebMediaPlayerClientImpl::durationChanged() 156 { 157 ASSERT(m_mediaPlayer); 158 m_mediaPlayer->durationChanged(); 159 } 160 161 void WebMediaPlayerClientImpl::rateChanged() 162 { 163 ASSERT(m_mediaPlayer); 164 m_mediaPlayer->rateChanged(); 165 } 166 167 void WebMediaPlayerClientImpl::sizeChanged() 168 { 169 ASSERT(m_mediaPlayer); 170 m_mediaPlayer->sizeChanged(); 171 } 172 173 void WebMediaPlayerClientImpl::sawUnsupportedTracks() 174 { 175 ASSERT(m_mediaPlayer); 176 m_mediaPlayer->mediaPlayerClient()->mediaPlayerSawUnsupportedTracks(m_mediaPlayer); 177 } 178 179 float WebMediaPlayerClientImpl::volume() const 180 { 181 if (m_mediaPlayer) 182 return m_mediaPlayer->volume(); 183 return 0.0f; 184 } 185 186 void WebMediaPlayerClientImpl::playbackStateChanged() 187 { 188 ASSERT(m_mediaPlayer); 189 m_mediaPlayer->playbackStateChanged(); 190 } 191 192 WebMediaPlayer::Preload WebMediaPlayerClientImpl::preload() const 193 { 194 if (m_mediaPlayer) 195 return static_cast<WebMediaPlayer::Preload>(m_mediaPlayer->preload()); 196 return static_cast<WebMediaPlayer::Preload>(m_preload); 197 } 198 199 // MediaPlayerPrivateInterface ------------------------------------------------- 200 201 void WebMediaPlayerClientImpl::load(const String& url) 202 { 203 m_url = url; 204 205 // Video frame object is owned by WebMediaPlayer. Before destroying 206 // WebMediaPlayer all frames need to be released. 207 #if USE(ACCELERATED_COMPOSITING) 208 if (m_videoLayer.get()) 209 m_videoLayer->releaseCurrentFrame(); 210 #endif 211 212 if (m_preload == MediaPlayer::None) { 213 m_webMediaPlayer.clear(); 214 m_delayingLoad = true; 215 } else 216 loadInternal(); 217 } 218 219 void WebMediaPlayerClientImpl::loadInternal() 220 { 221 Frame* frame = static_cast<HTMLMediaElement*>(m_mediaPlayer->mediaPlayerClient())->document()->frame(); 222 m_webMediaPlayer.set(createWebMediaPlayer(this, frame)); 223 if (m_webMediaPlayer.get()) 224 m_webMediaPlayer->load(KURL(ParsedURLString, m_url)); 225 } 226 227 void WebMediaPlayerClientImpl::cancelLoad() 228 { 229 if (m_webMediaPlayer.get()) 230 m_webMediaPlayer->cancelLoad(); 231 } 232 233 #if USE(ACCELERATED_COMPOSITING) 234 PlatformLayer* WebMediaPlayerClientImpl::platformLayer() const 235 { 236 ASSERT(m_supportsAcceleratedCompositing); 237 return m_videoLayer.get(); 238 } 239 #endif 240 241 PlatformMedia WebMediaPlayerClientImpl::platformMedia() const 242 { 243 PlatformMedia pm; 244 pm.type = PlatformMedia::ChromiumMediaPlayerType; 245 pm.media.chromiumMediaPlayer = const_cast<WebMediaPlayerClientImpl*>(this); 246 return pm; 247 } 248 249 void WebMediaPlayerClientImpl::play() 250 { 251 if (m_webMediaPlayer.get()) 252 m_webMediaPlayer->play(); 253 } 254 255 void WebMediaPlayerClientImpl::pause() 256 { 257 if (m_webMediaPlayer.get()) 258 m_webMediaPlayer->pause(); 259 } 260 261 void WebMediaPlayerClientImpl::prepareToPlay() 262 { 263 if (m_delayingLoad) 264 startDelayedLoad(); 265 } 266 267 IntSize WebMediaPlayerClientImpl::naturalSize() const 268 { 269 if (m_webMediaPlayer.get()) 270 return m_webMediaPlayer->naturalSize(); 271 return IntSize(); 272 } 273 274 bool WebMediaPlayerClientImpl::hasVideo() const 275 { 276 if (m_webMediaPlayer.get()) 277 return m_webMediaPlayer->hasVideo(); 278 return false; 279 } 280 281 bool WebMediaPlayerClientImpl::hasAudio() const 282 { 283 if (m_webMediaPlayer.get()) 284 return m_webMediaPlayer->hasAudio(); 285 return false; 286 } 287 288 void WebMediaPlayerClientImpl::setVisible(bool visible) 289 { 290 if (m_webMediaPlayer.get()) 291 m_webMediaPlayer->setVisible(visible); 292 } 293 294 float WebMediaPlayerClientImpl::duration() const 295 { 296 if (m_webMediaPlayer.get()) 297 return m_webMediaPlayer->duration(); 298 return 0.0f; 299 } 300 301 float WebMediaPlayerClientImpl::currentTime() const 302 { 303 if (m_webMediaPlayer.get()) 304 return m_webMediaPlayer->currentTime(); 305 return 0.0f; 306 } 307 308 void WebMediaPlayerClientImpl::seek(float time) 309 { 310 if (m_webMediaPlayer.get()) 311 m_webMediaPlayer->seek(time); 312 } 313 314 bool WebMediaPlayerClientImpl::seeking() const 315 { 316 if (m_webMediaPlayer.get()) 317 return m_webMediaPlayer->seeking(); 318 return false; 319 } 320 321 void WebMediaPlayerClientImpl::setEndTime(float time) 322 { 323 if (m_webMediaPlayer.get()) 324 m_webMediaPlayer->setEndTime(time); 325 } 326 327 void WebMediaPlayerClientImpl::setRate(float rate) 328 { 329 if (m_webMediaPlayer.get()) 330 m_webMediaPlayer->setRate(rate); 331 } 332 333 bool WebMediaPlayerClientImpl::paused() const 334 { 335 if (m_webMediaPlayer.get()) 336 return m_webMediaPlayer->paused(); 337 return false; 338 } 339 340 bool WebMediaPlayerClientImpl::supportsFullscreen() const 341 { 342 if (m_webMediaPlayer.get()) 343 return m_webMediaPlayer->supportsFullscreen(); 344 return false; 345 } 346 347 bool WebMediaPlayerClientImpl::supportsSave() const 348 { 349 if (m_webMediaPlayer.get()) 350 return m_webMediaPlayer->supportsSave(); 351 return false; 352 } 353 354 void WebMediaPlayerClientImpl::setVolume(float volume) 355 { 356 if (m_webMediaPlayer.get()) 357 m_webMediaPlayer->setVolume(volume); 358 } 359 360 MediaPlayer::NetworkState WebMediaPlayerClientImpl::networkState() const 361 { 362 if (m_webMediaPlayer.get()) 363 return static_cast<MediaPlayer::NetworkState>(m_webMediaPlayer->networkState()); 364 return MediaPlayer::Empty; 365 } 366 367 MediaPlayer::ReadyState WebMediaPlayerClientImpl::readyState() const 368 { 369 if (m_webMediaPlayer.get()) 370 return static_cast<MediaPlayer::ReadyState>(m_webMediaPlayer->readyState()); 371 return MediaPlayer::HaveNothing; 372 } 373 374 float WebMediaPlayerClientImpl::maxTimeSeekable() const 375 { 376 if (m_webMediaPlayer.get()) 377 return m_webMediaPlayer->maxTimeSeekable(); 378 return 0.0f; 379 } 380 381 PassRefPtr<TimeRanges> WebMediaPlayerClientImpl::buffered() const 382 { 383 if (m_webMediaPlayer.get()) { 384 const WebTimeRanges& webRanges = m_webMediaPlayer->buffered(); 385 386 // FIXME: Save the time ranges in a member variable and update it when needed. 387 RefPtr<TimeRanges> ranges = TimeRanges::create(); 388 for (size_t i = 0; i < webRanges.size(); ++i) 389 ranges->add(webRanges[i].start, webRanges[i].end); 390 return ranges.release(); 391 } 392 return TimeRanges::create(); 393 } 394 395 int WebMediaPlayerClientImpl::dataRate() const 396 { 397 if (m_webMediaPlayer.get()) 398 return m_webMediaPlayer->dataRate(); 399 return 0; 400 } 401 402 bool WebMediaPlayerClientImpl::totalBytesKnown() const 403 { 404 if (m_webMediaPlayer.get()) 405 return m_webMediaPlayer->totalBytesKnown(); 406 return false; 407 } 408 409 unsigned WebMediaPlayerClientImpl::totalBytes() const 410 { 411 if (m_webMediaPlayer.get()) 412 return static_cast<unsigned>(m_webMediaPlayer->totalBytes()); 413 return 0; 414 } 415 416 unsigned WebMediaPlayerClientImpl::bytesLoaded() const 417 { 418 if (m_webMediaPlayer.get()) 419 return static_cast<unsigned>(m_webMediaPlayer->bytesLoaded()); 420 return 0; 421 } 422 423 void WebMediaPlayerClientImpl::setSize(const IntSize& size) 424 { 425 if (m_webMediaPlayer.get()) 426 m_webMediaPlayer->setSize(WebSize(size.width(), size.height())); 427 } 428 429 void WebMediaPlayerClientImpl::paint(GraphicsContext* context, const IntRect& rect) 430 { 431 #if USE(ACCELERATED_COMPOSITING) 432 // If we are using GPU to render video, ignore requests to paint frames into 433 // canvas because it will be taken care of by VideoLayerChromium. 434 if (acceleratedRenderingInUse()) 435 return; 436 #endif 437 paintCurrentFrameInContext(context, rect); 438 } 439 440 void WebMediaPlayerClientImpl::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& rect) 441 { 442 // Normally GraphicsContext operations do nothing when painting is disabled. 443 // Since we're accessing platformContext() directly we have to manually 444 // check. 445 if (m_webMediaPlayer.get() && !context->paintingDisabled()) { 446 #if WEBKIT_USING_SKIA 447 PlatformGraphicsContext* platformContext = context->platformContext(); 448 WebCanvas* canvas = platformContext->canvas(); 449 450 canvas->saveLayerAlpha(0, platformContext->getNormalizedAlpha()); 451 452 m_webMediaPlayer->paint(canvas, rect); 453 454 canvas->restore(); 455 #elif WEBKIT_USING_CG 456 m_webMediaPlayer->paint(context->platformContext(), rect); 457 #else 458 notImplemented(); 459 #endif 460 } 461 } 462 463 void WebMediaPlayerClientImpl::setPreload(MediaPlayer::Preload preload) 464 { 465 m_preload = preload; 466 467 if (m_webMediaPlayer.get()) 468 m_webMediaPlayer->setPreload(static_cast<WebMediaPlayer::Preload>(preload)); 469 470 if (m_delayingLoad && m_preload != MediaPlayer::None) 471 startDelayedLoad(); 472 } 473 474 bool WebMediaPlayerClientImpl::hasSingleSecurityOrigin() const 475 { 476 if (m_webMediaPlayer.get()) 477 return m_webMediaPlayer->hasSingleSecurityOrigin(); 478 return false; 479 } 480 481 MediaPlayer::MovieLoadType WebMediaPlayerClientImpl::movieLoadType() const 482 { 483 if (m_webMediaPlayer.get()) 484 return static_cast<MediaPlayer::MovieLoadType>( 485 m_webMediaPlayer->movieLoadType()); 486 return MediaPlayer::Unknown; 487 } 488 489 unsigned WebMediaPlayerClientImpl::decodedFrameCount() const 490 { 491 if (m_webMediaPlayer.get()) 492 return m_webMediaPlayer->decodedFrameCount(); 493 return 0; 494 } 495 496 unsigned WebMediaPlayerClientImpl::droppedFrameCount() const 497 { 498 if (m_webMediaPlayer.get()) 499 return m_webMediaPlayer->droppedFrameCount(); 500 return 0; 501 } 502 503 unsigned WebMediaPlayerClientImpl::audioDecodedByteCount() const 504 { 505 if (m_webMediaPlayer.get()) 506 return m_webMediaPlayer->audioDecodedByteCount(); 507 return 0; 508 } 509 510 unsigned WebMediaPlayerClientImpl::videoDecodedByteCount() const 511 { 512 if (m_webMediaPlayer.get()) 513 return m_webMediaPlayer->videoDecodedByteCount(); 514 return 0; 515 } 516 517 #if USE(ACCELERATED_COMPOSITING) 518 bool WebMediaPlayerClientImpl::supportsAcceleratedRendering() const 519 { 520 return m_supportsAcceleratedCompositing; 521 } 522 523 bool WebMediaPlayerClientImpl::acceleratedRenderingInUse() 524 { 525 return m_videoLayer.get() && m_videoLayer->layerRenderer(); 526 } 527 528 VideoFrameChromium* WebMediaPlayerClientImpl::getCurrentFrame() 529 { 530 VideoFrameChromium* videoFrame = 0; 531 if (m_webMediaPlayer.get()) { 532 WebVideoFrame* webkitVideoFrame = m_webMediaPlayer->getCurrentFrame(); 533 if (webkitVideoFrame) 534 videoFrame = new VideoFrameChromiumImpl(webkitVideoFrame); 535 } 536 return videoFrame; 537 } 538 539 void WebMediaPlayerClientImpl::putCurrentFrame(VideoFrameChromium* videoFrame) 540 { 541 if (videoFrame) { 542 if (m_webMediaPlayer.get()) { 543 m_webMediaPlayer->putCurrentFrame( 544 VideoFrameChromiumImpl::toWebVideoFrame(videoFrame)); 545 } 546 delete videoFrame; 547 } 548 } 549 #endif 550 551 MediaPlayerPrivateInterface* WebMediaPlayerClientImpl::create(MediaPlayer* player) 552 { 553 WebMediaPlayerClientImpl* client = new WebMediaPlayerClientImpl(); 554 client->m_mediaPlayer = player; 555 556 #if USE(ACCELERATED_COMPOSITING) 557 Frame* frame = static_cast<HTMLMediaElement*>( 558 client->m_mediaPlayer->mediaPlayerClient())->document()->frame(); 559 560 // This does not actually check whether the hardware can support accelerated 561 // compositing, but only if the flag is set. However, this is checked lazily 562 // in WebViewImpl::setIsAcceleratedCompositingActive() and will fail there 563 // if necessary. 564 client->m_supportsAcceleratedCompositing = 565 frame->contentRenderer()->compositor()->hasAcceleratedCompositing(); 566 #endif 567 568 return client; 569 } 570 571 void WebMediaPlayerClientImpl::getSupportedTypes(HashSet<String>& supportedTypes) 572 { 573 // FIXME: integrate this list with WebMediaPlayerClientImpl::supportsType. 574 notImplemented(); 575 } 576 577 MediaPlayer::SupportsType WebMediaPlayerClientImpl::supportsType(const String& type, 578 const String& codecs) 579 { 580 WebMimeRegistry::SupportsType supportsType = 581 webKitClient()->mimeRegistry()->supportsMediaMIMEType(type, codecs); 582 583 switch (supportsType) { 584 default: 585 ASSERT_NOT_REACHED(); 586 case WebMimeRegistry::IsNotSupported: 587 return MediaPlayer::IsNotSupported; 588 case WebMimeRegistry::IsSupported: 589 return MediaPlayer::IsSupported; 590 case WebMimeRegistry::MayBeSupported: 591 return MediaPlayer::MayBeSupported; 592 } 593 return MediaPlayer::IsNotSupported; 594 } 595 596 void WebMediaPlayerClientImpl::startDelayedLoad() 597 { 598 ASSERT(m_delayingLoad); 599 ASSERT(!m_webMediaPlayer.get()); 600 601 m_delayingLoad = false; 602 603 loadInternal(); 604 } 605 606 WebMediaPlayerClientImpl::WebMediaPlayerClientImpl() 607 : m_mediaPlayer(0) 608 , m_delayingLoad(false) 609 , m_preload(MediaPlayer::MetaData) 610 #if USE(ACCELERATED_COMPOSITING) 611 , m_videoLayer(0) 612 , m_supportsAcceleratedCompositing(false) 613 #endif 614 { 615 } 616 617 } // namespace WebKit 618 619 #endif // ENABLE(VIDEO) 620