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 50using namespace WebCore; 51 52namespace WebKit { 53 54static 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 64bool WebMediaPlayerClientImpl::m_isEnabled = false; 65 66bool WebMediaPlayerClientImpl::isEnabled() 67{ 68 return m_isEnabled; 69} 70 71void WebMediaPlayerClientImpl::setIsEnabled(bool isEnabled) 72{ 73 m_isEnabled = isEnabled; 74} 75 76void 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 88WebMediaPlayerClientImpl* WebMediaPlayerClientImpl::fromMediaElement(const WebMediaElement* element) 89{ 90 PlatformMedia pm = element->constUnwrap<HTMLMediaElement>()->platformMedia(); 91 return static_cast<WebMediaPlayerClientImpl*>(pm.media.chromiumMediaPlayer); 92} 93 94WebMediaPlayer* WebMediaPlayerClientImpl::mediaPlayer() const 95{ 96 return m_webMediaPlayer.get(); 97} 98 99// WebMediaPlayerClient -------------------------------------------------------- 100 101WebMediaPlayerClientImpl::~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 111void WebMediaPlayerClientImpl::networkStateChanged() 112{ 113 ASSERT(m_mediaPlayer); 114 m_mediaPlayer->networkStateChanged(); 115} 116 117void 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 127void WebMediaPlayerClientImpl::volumeChanged(float newVolume) 128{ 129 ASSERT(m_mediaPlayer); 130 m_mediaPlayer->volumeChanged(newVolume); 131} 132 133void WebMediaPlayerClientImpl::muteChanged(bool newMute) 134{ 135 ASSERT(m_mediaPlayer); 136 m_mediaPlayer->muteChanged(newMute); 137} 138 139void WebMediaPlayerClientImpl::timeChanged() 140{ 141 ASSERT(m_mediaPlayer); 142 m_mediaPlayer->timeChanged(); 143} 144 145void 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 155void WebMediaPlayerClientImpl::durationChanged() 156{ 157 ASSERT(m_mediaPlayer); 158 m_mediaPlayer->durationChanged(); 159} 160 161void WebMediaPlayerClientImpl::rateChanged() 162{ 163 ASSERT(m_mediaPlayer); 164 m_mediaPlayer->rateChanged(); 165} 166 167void WebMediaPlayerClientImpl::sizeChanged() 168{ 169 ASSERT(m_mediaPlayer); 170 m_mediaPlayer->sizeChanged(); 171} 172 173void WebMediaPlayerClientImpl::sawUnsupportedTracks() 174{ 175 ASSERT(m_mediaPlayer); 176 m_mediaPlayer->mediaPlayerClient()->mediaPlayerSawUnsupportedTracks(m_mediaPlayer); 177} 178 179float WebMediaPlayerClientImpl::volume() const 180{ 181 if (m_mediaPlayer) 182 return m_mediaPlayer->volume(); 183 return 0.0f; 184} 185 186void WebMediaPlayerClientImpl::playbackStateChanged() 187{ 188 ASSERT(m_mediaPlayer); 189 m_mediaPlayer->playbackStateChanged(); 190} 191 192WebMediaPlayer::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 201void 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 219void 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 227void WebMediaPlayerClientImpl::cancelLoad() 228{ 229 if (m_webMediaPlayer.get()) 230 m_webMediaPlayer->cancelLoad(); 231} 232 233#if USE(ACCELERATED_COMPOSITING) 234PlatformLayer* WebMediaPlayerClientImpl::platformLayer() const 235{ 236 ASSERT(m_supportsAcceleratedCompositing); 237 return m_videoLayer.get(); 238} 239#endif 240 241PlatformMedia 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 249void WebMediaPlayerClientImpl::play() 250{ 251 if (m_webMediaPlayer.get()) 252 m_webMediaPlayer->play(); 253} 254 255void WebMediaPlayerClientImpl::pause() 256{ 257 if (m_webMediaPlayer.get()) 258 m_webMediaPlayer->pause(); 259} 260 261void WebMediaPlayerClientImpl::prepareToPlay() 262{ 263 if (m_delayingLoad) 264 startDelayedLoad(); 265} 266 267IntSize WebMediaPlayerClientImpl::naturalSize() const 268{ 269 if (m_webMediaPlayer.get()) 270 return m_webMediaPlayer->naturalSize(); 271 return IntSize(); 272} 273 274bool WebMediaPlayerClientImpl::hasVideo() const 275{ 276 if (m_webMediaPlayer.get()) 277 return m_webMediaPlayer->hasVideo(); 278 return false; 279} 280 281bool WebMediaPlayerClientImpl::hasAudio() const 282{ 283 if (m_webMediaPlayer.get()) 284 return m_webMediaPlayer->hasAudio(); 285 return false; 286} 287 288void WebMediaPlayerClientImpl::setVisible(bool visible) 289{ 290 if (m_webMediaPlayer.get()) 291 m_webMediaPlayer->setVisible(visible); 292} 293 294float WebMediaPlayerClientImpl::duration() const 295{ 296 if (m_webMediaPlayer.get()) 297 return m_webMediaPlayer->duration(); 298 return 0.0f; 299} 300 301float WebMediaPlayerClientImpl::currentTime() const 302{ 303 if (m_webMediaPlayer.get()) 304 return m_webMediaPlayer->currentTime(); 305 return 0.0f; 306} 307 308void WebMediaPlayerClientImpl::seek(float time) 309{ 310 if (m_webMediaPlayer.get()) 311 m_webMediaPlayer->seek(time); 312} 313 314bool WebMediaPlayerClientImpl::seeking() const 315{ 316 if (m_webMediaPlayer.get()) 317 return m_webMediaPlayer->seeking(); 318 return false; 319} 320 321void WebMediaPlayerClientImpl::setEndTime(float time) 322{ 323 if (m_webMediaPlayer.get()) 324 m_webMediaPlayer->setEndTime(time); 325} 326 327void WebMediaPlayerClientImpl::setRate(float rate) 328{ 329 if (m_webMediaPlayer.get()) 330 m_webMediaPlayer->setRate(rate); 331} 332 333bool WebMediaPlayerClientImpl::paused() const 334{ 335 if (m_webMediaPlayer.get()) 336 return m_webMediaPlayer->paused(); 337 return false; 338} 339 340bool WebMediaPlayerClientImpl::supportsFullscreen() const 341{ 342 if (m_webMediaPlayer.get()) 343 return m_webMediaPlayer->supportsFullscreen(); 344 return false; 345} 346 347bool WebMediaPlayerClientImpl::supportsSave() const 348{ 349 if (m_webMediaPlayer.get()) 350 return m_webMediaPlayer->supportsSave(); 351 return false; 352} 353 354void WebMediaPlayerClientImpl::setVolume(float volume) 355{ 356 if (m_webMediaPlayer.get()) 357 m_webMediaPlayer->setVolume(volume); 358} 359 360MediaPlayer::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 367MediaPlayer::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 374float WebMediaPlayerClientImpl::maxTimeSeekable() const 375{ 376 if (m_webMediaPlayer.get()) 377 return m_webMediaPlayer->maxTimeSeekable(); 378 return 0.0f; 379} 380 381PassRefPtr<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 395int WebMediaPlayerClientImpl::dataRate() const 396{ 397 if (m_webMediaPlayer.get()) 398 return m_webMediaPlayer->dataRate(); 399 return 0; 400} 401 402bool WebMediaPlayerClientImpl::totalBytesKnown() const 403{ 404 if (m_webMediaPlayer.get()) 405 return m_webMediaPlayer->totalBytesKnown(); 406 return false; 407} 408 409unsigned WebMediaPlayerClientImpl::totalBytes() const 410{ 411 if (m_webMediaPlayer.get()) 412 return static_cast<unsigned>(m_webMediaPlayer->totalBytes()); 413 return 0; 414} 415 416unsigned WebMediaPlayerClientImpl::bytesLoaded() const 417{ 418 if (m_webMediaPlayer.get()) 419 return static_cast<unsigned>(m_webMediaPlayer->bytesLoaded()); 420 return 0; 421} 422 423void WebMediaPlayerClientImpl::setSize(const IntSize& size) 424{ 425 if (m_webMediaPlayer.get()) 426 m_webMediaPlayer->setSize(WebSize(size.width(), size.height())); 427} 428 429void 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 440void 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 463void 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 474bool WebMediaPlayerClientImpl::hasSingleSecurityOrigin() const 475{ 476 if (m_webMediaPlayer.get()) 477 return m_webMediaPlayer->hasSingleSecurityOrigin(); 478 return false; 479} 480 481MediaPlayer::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 489unsigned WebMediaPlayerClientImpl::decodedFrameCount() const 490{ 491 if (m_webMediaPlayer.get()) 492 return m_webMediaPlayer->decodedFrameCount(); 493 return 0; 494} 495 496unsigned WebMediaPlayerClientImpl::droppedFrameCount() const 497{ 498 if (m_webMediaPlayer.get()) 499 return m_webMediaPlayer->droppedFrameCount(); 500 return 0; 501} 502 503unsigned WebMediaPlayerClientImpl::audioDecodedByteCount() const 504{ 505 if (m_webMediaPlayer.get()) 506 return m_webMediaPlayer->audioDecodedByteCount(); 507 return 0; 508} 509 510unsigned WebMediaPlayerClientImpl::videoDecodedByteCount() const 511{ 512 if (m_webMediaPlayer.get()) 513 return m_webMediaPlayer->videoDecodedByteCount(); 514 return 0; 515} 516 517#if USE(ACCELERATED_COMPOSITING) 518bool WebMediaPlayerClientImpl::supportsAcceleratedRendering() const 519{ 520 return m_supportsAcceleratedCompositing; 521} 522 523bool WebMediaPlayerClientImpl::acceleratedRenderingInUse() 524{ 525 return m_videoLayer.get() && m_videoLayer->layerRenderer(); 526} 527 528VideoFrameChromium* 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 539void 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 551MediaPlayerPrivateInterface* 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 571void WebMediaPlayerClientImpl::getSupportedTypes(HashSet<String>& supportedTypes) 572{ 573 // FIXME: integrate this list with WebMediaPlayerClientImpl::supportsType. 574 notImplemented(); 575} 576 577MediaPlayer::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 596void WebMediaPlayerClientImpl::startDelayedLoad() 597{ 598 ASSERT(m_delayingLoad); 599 ASSERT(!m_webMediaPlayer.get()); 600 601 m_delayingLoad = false; 602 603 loadInternal(); 604} 605 606WebMediaPlayerClientImpl::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