Home | History | Annotate | Download | only in web
      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 #include "WebDocument.h"
      9 #include "WebFrameClient.h"
     10 #include "WebFrameImpl.h"
     11 #include "WebHelperPluginImpl.h"
     12 #include "WebViewImpl.h"
     13 #include "core/frame/Frame.h"
     14 #include "core/html/HTMLMediaElement.h"
     15 #include "core/html/HTMLMediaSource.h"
     16 #include "core/html/TimeRanges.h"
     17 #include "core/rendering/RenderLayerCompositor.h"
     18 #include "core/rendering/RenderView.h"
     19 #include "modules/mediastream/MediaStreamRegistry.h"
     20 #include "platform/audio/AudioBus.h"
     21 #include "platform/audio/AudioSourceProviderClient.h"
     22 #include "platform/geometry/IntSize.h"
     23 #include "platform/graphics/GraphicsContext.h"
     24 #include "platform/graphics/GraphicsContext3D.h"
     25 #include "platform/graphics/GraphicsLayer.h"
     26 #include "platform/graphics/skia/GaneshUtils.h"
     27 #include "public/platform/WebAudioSourceProvider.h"
     28 #include "public/platform/WebCString.h"
     29 #include "public/platform/WebCanvas.h"
     30 #include "public/platform/WebCompositorSupport.h"
     31 #include "public/platform/WebInbandTextTrack.h"
     32 #include "public/platform/WebMediaPlayer.h"
     33 #include "public/platform/WebRect.h"
     34 #include "public/platform/WebString.h"
     35 #include "public/platform/WebURL.h"
     36 
     37 #if OS(ANDROID)
     38 #include "GrContext.h"
     39 #include "GrTypes.h"
     40 #include "SkCanvas.h"
     41 #include "SkGrPixelRef.h"
     42 #include "platform/graphics/gpu/SharedGraphicsContext3D.h"
     43 #endif
     44 
     45 
     46 #include "wtf/Assertions.h"
     47 #include "wtf/text/CString.h"
     48 
     49 using namespace WebCore;
     50 
     51 namespace blink {
     52 
     53 static PassOwnPtr<WebMediaPlayer> createWebMediaPlayer(WebMediaPlayerClient* client, const WebURL& url, Frame* frame)
     54 {
     55     WebFrameImpl* webFrame = WebFrameImpl::fromFrame(frame);
     56 
     57     if (!webFrame->client())
     58         return nullptr;
     59     return adoptPtr(webFrame->client()->createMediaPlayer(webFrame, url, client));
     60 }
     61 
     62 WebMediaPlayer* WebMediaPlayerClientImpl::mediaPlayer() const
     63 {
     64     return m_webMediaPlayer.get();
     65 }
     66 
     67 // WebMediaPlayerClient --------------------------------------------------------
     68 
     69 WebMediaPlayerClientImpl::~WebMediaPlayerClientImpl()
     70 {
     71     // Explicitly destroy the WebMediaPlayer to allow verification of tear down.
     72     m_webMediaPlayer.clear();
     73 
     74     // Ensure the m_webMediaPlayer destroyed any WebHelperPlugin used.
     75     ASSERT(!m_helperPlugin);
     76 }
     77 
     78 void WebMediaPlayerClientImpl::networkStateChanged()
     79 {
     80     m_client->mediaPlayerNetworkStateChanged();
     81 }
     82 
     83 void WebMediaPlayerClientImpl::readyStateChanged()
     84 {
     85     m_client->mediaPlayerReadyStateChanged();
     86 }
     87 
     88 void WebMediaPlayerClientImpl::timeChanged()
     89 {
     90     m_client->mediaPlayerTimeChanged();
     91 }
     92 
     93 void WebMediaPlayerClientImpl::repaint()
     94 {
     95     m_client->mediaPlayerRepaint();
     96 }
     97 
     98 void WebMediaPlayerClientImpl::durationChanged()
     99 {
    100     m_client->mediaPlayerDurationChanged();
    101 }
    102 
    103 void WebMediaPlayerClientImpl::sizeChanged()
    104 {
    105     m_client->mediaPlayerSizeChanged();
    106 }
    107 
    108 void WebMediaPlayerClientImpl::setOpaque(bool opaque)
    109 {
    110     m_client->mediaPlayerSetOpaque(opaque);
    111 }
    112 
    113 double WebMediaPlayerClientImpl::volume() const
    114 {
    115     return m_volume;
    116 }
    117 
    118 void WebMediaPlayerClientImpl::playbackStateChanged()
    119 {
    120     m_client->mediaPlayerPlaybackStateChanged();
    121 }
    122 
    123 WebMediaPlayer::Preload WebMediaPlayerClientImpl::preload() const
    124 {
    125     return static_cast<WebMediaPlayer::Preload>(m_preload);
    126 }
    127 
    128 void WebMediaPlayerClientImpl::keyAdded(const WebString& keySystem, const WebString& sessionId)
    129 {
    130     m_client->mediaPlayerKeyAdded(keySystem, sessionId);
    131 }
    132 
    133 void WebMediaPlayerClientImpl::keyError(const WebString& keySystem, const WebString& sessionId, MediaKeyErrorCode errorCode, unsigned short systemCode)
    134 {
    135     m_client->mediaPlayerKeyError(keySystem, sessionId, static_cast<MediaPlayerClient::MediaKeyErrorCode>(errorCode), systemCode);
    136 }
    137 
    138 void WebMediaPlayerClientImpl::keyMessage(const WebString& keySystem, const WebString& sessionId, const unsigned char* message, unsigned messageLength, const WebURL& defaultURL)
    139 {
    140     m_client->mediaPlayerKeyMessage(keySystem, sessionId, message, messageLength, defaultURL);
    141 }
    142 
    143 void WebMediaPlayerClientImpl::keyNeeded(const WebString& keySystem, const WebString& sessionId, const unsigned char* initData, unsigned initDataLength)
    144 {
    145     m_client->mediaPlayerKeyNeeded(keySystem, sessionId, initData, initDataLength);
    146 }
    147 
    148 WebPlugin* WebMediaPlayerClientImpl::createHelperPlugin(const WebString& pluginType, WebFrame* frame)
    149 {
    150     ASSERT(!m_helperPlugin);
    151 
    152     m_helperPlugin = toWebViewImpl(frame->view())->createHelperPlugin(pluginType, frame->document());
    153     if (!m_helperPlugin)
    154         return 0;
    155 
    156     WebPlugin* plugin = m_helperPlugin->getPlugin();
    157     if (!plugin) {
    158         // There is no need to keep the helper plugin around and the caller
    159         // should not be expected to call close after a failure (null pointer).
    160         closeHelperPluginSoon(frame);
    161         return 0;
    162     }
    163 
    164     return plugin;
    165 }
    166 
    167 
    168 void WebMediaPlayerClientImpl::closeHelperPluginSoon(WebFrame* frame)
    169 {
    170     ASSERT(m_helperPlugin);
    171     toWebViewImpl(frame->view())->closeHelperPluginSoon(m_helperPlugin.release());
    172 }
    173 
    174 void WebMediaPlayerClientImpl::setWebLayer(blink::WebLayer* layer)
    175 {
    176     m_client->mediaPlayerSetWebLayer(layer);
    177 }
    178 
    179 void WebMediaPlayerClientImpl::addTextTrack(WebInbandTextTrack* textTrack)
    180 {
    181     m_client->mediaPlayerDidAddTrack(textTrack);
    182 }
    183 
    184 void WebMediaPlayerClientImpl::removeTextTrack(WebInbandTextTrack* textTrack)
    185 {
    186     m_client->mediaPlayerDidRemoveTrack(textTrack);
    187 }
    188 
    189 void WebMediaPlayerClientImpl::mediaSourceOpened(WebMediaSource* webMediaSource)
    190 {
    191     ASSERT(webMediaSource);
    192     m_mediaSource->setWebMediaSourceAndOpen(adoptPtr(webMediaSource));
    193     m_mediaSource = 0;
    194 }
    195 
    196 void WebMediaPlayerClientImpl::requestFullscreen()
    197 {
    198     m_client->mediaPlayerRequestFullscreen();
    199 }
    200 
    201 void WebMediaPlayerClientImpl::requestSeek(double time)
    202 {
    203     m_client->mediaPlayerRequestSeek(time);
    204 }
    205 
    206 // MediaPlayer -------------------------------------------------
    207 
    208 void WebMediaPlayerClientImpl::load(const String& url)
    209 {
    210     m_url = KURL(ParsedURLString, url);
    211     m_mediaSource = 0;
    212     loadRequested();
    213 }
    214 
    215 void WebMediaPlayerClientImpl::load(const String& url, PassRefPtr<WebCore::HTMLMediaSource> mediaSource)
    216 {
    217     m_url = KURL(ParsedURLString, url);
    218     m_mediaSource = mediaSource;
    219     loadRequested();
    220 }
    221 
    222 void WebMediaPlayerClientImpl::loadRequested()
    223 {
    224     if (m_preload == MediaPlayer::None) {
    225 #if ENABLE(WEB_AUDIO)
    226         m_audioSourceProvider.wrap(0); // Clear weak reference to m_webMediaPlayer's WebAudioSourceProvider.
    227 #endif
    228         m_webMediaPlayer.clear();
    229         m_delayingLoad = true;
    230     } else
    231         loadInternal();
    232 }
    233 
    234 void WebMediaPlayerClientImpl::loadInternal()
    235 {
    236     m_isMediaStream = WebCore::MediaStreamRegistry::registry().lookupMediaStreamDescriptor(m_url.string());
    237 
    238 #if ENABLE(WEB_AUDIO)
    239     m_audioSourceProvider.wrap(0); // Clear weak reference to m_webMediaPlayer's WebAudioSourceProvider.
    240 #endif
    241 
    242     // FIXME: Remove this cast
    243     Frame* frame = static_cast<HTMLMediaElement*>(m_client)->document().frame();
    244 
    245     // This does not actually check whether the hardware can support accelerated
    246     // compositing, but only if the flag is set. However, this is checked lazily
    247     // in WebViewImpl::setIsAcceleratedCompositingActive() and will fail there
    248     // if necessary.
    249     m_needsWebLayerForVideo = frame->contentRenderer()->compositor()->hasAcceleratedCompositing();
    250 
    251     m_webMediaPlayer = createWebMediaPlayer(this, m_url, frame);
    252     if (m_webMediaPlayer) {
    253 #if ENABLE(WEB_AUDIO)
    254         // Make sure if we create/re-create the WebMediaPlayer that we update our wrapper.
    255         m_audioSourceProvider.wrap(m_webMediaPlayer->audioSourceProvider());
    256 #endif
    257 
    258         WebMediaPlayer::LoadType loadType = WebMediaPlayer::LoadTypeURL;
    259 
    260         if (m_mediaSource)
    261             loadType = WebMediaPlayer::LoadTypeMediaSource;
    262         else if (m_isMediaStream)
    263             loadType = WebMediaPlayer::LoadTypeMediaStream;
    264 
    265         WebMediaPlayer::CORSMode corsMode = static_cast<WebMediaPlayer::CORSMode>(m_client->mediaPlayerCORSMode());
    266         m_webMediaPlayer->load(loadType, m_url, corsMode);
    267     }
    268 }
    269 
    270 void WebMediaPlayerClientImpl::play()
    271 {
    272     if (m_webMediaPlayer)
    273         m_webMediaPlayer->play();
    274 }
    275 
    276 void WebMediaPlayerClientImpl::pause()
    277 {
    278     if (m_webMediaPlayer)
    279         m_webMediaPlayer->pause();
    280 }
    281 
    282 void WebMediaPlayerClientImpl::showFullscreenOverlay()
    283 {
    284     if (m_webMediaPlayer)
    285         m_webMediaPlayer->enterFullscreen();
    286 }
    287 
    288 void WebMediaPlayerClientImpl::hideFullscreenOverlay()
    289 {
    290     if (m_webMediaPlayer)
    291         m_webMediaPlayer->exitFullscreen();
    292 }
    293 
    294 bool WebMediaPlayerClientImpl::canShowFullscreenOverlay() const
    295 {
    296     return m_webMediaPlayer && m_webMediaPlayer->canEnterFullscreen();
    297 }
    298 
    299 MediaPlayer::MediaKeyException WebMediaPlayerClientImpl::generateKeyRequest(const String& keySystem, const unsigned char* initData, unsigned initDataLength)
    300 {
    301     if (!m_webMediaPlayer)
    302         return MediaPlayer::InvalidPlayerState;
    303 
    304     WebMediaPlayer::MediaKeyException result = m_webMediaPlayer->generateKeyRequest(keySystem, initData, initDataLength);
    305     return static_cast<MediaPlayer::MediaKeyException>(result);
    306 }
    307 
    308 MediaPlayer::MediaKeyException WebMediaPlayerClientImpl::addKey(const String& keySystem, const unsigned char* key, unsigned keyLength, const unsigned char* initData, unsigned initDataLength, const String& sessionId)
    309 {
    310     if (!m_webMediaPlayer)
    311         return MediaPlayer::InvalidPlayerState;
    312 
    313     WebMediaPlayer::MediaKeyException result = m_webMediaPlayer->addKey(keySystem, key, keyLength, initData, initDataLength, sessionId);
    314     return static_cast<MediaPlayer::MediaKeyException>(result);
    315 }
    316 
    317 MediaPlayer::MediaKeyException WebMediaPlayerClientImpl::cancelKeyRequest(const String& keySystem, const String& sessionId)
    318 {
    319     if (!m_webMediaPlayer)
    320         return MediaPlayer::InvalidPlayerState;
    321 
    322     WebMediaPlayer::MediaKeyException result = m_webMediaPlayer->cancelKeyRequest(keySystem, sessionId);
    323     return static_cast<MediaPlayer::MediaKeyException>(result);
    324 }
    325 
    326 void WebMediaPlayerClientImpl::prepareToPlay()
    327 {
    328     if (m_delayingLoad)
    329         startDelayedLoad();
    330 }
    331 
    332 IntSize WebMediaPlayerClientImpl::naturalSize() const
    333 {
    334     if (m_webMediaPlayer)
    335         return m_webMediaPlayer->naturalSize();
    336     return IntSize();
    337 }
    338 
    339 bool WebMediaPlayerClientImpl::hasVideo() const
    340 {
    341     if (m_webMediaPlayer)
    342         return m_webMediaPlayer->hasVideo();
    343     return false;
    344 }
    345 
    346 bool WebMediaPlayerClientImpl::hasAudio() const
    347 {
    348     if (m_webMediaPlayer)
    349         return m_webMediaPlayer->hasAudio();
    350     return false;
    351 }
    352 
    353 double WebMediaPlayerClientImpl::duration() const
    354 {
    355     if (m_webMediaPlayer)
    356         return m_webMediaPlayer->duration();
    357     return 0.0;
    358 }
    359 
    360 double WebMediaPlayerClientImpl::currentTime() const
    361 {
    362     if (m_webMediaPlayer)
    363         return m_webMediaPlayer->currentTime();
    364     return 0.0;
    365 }
    366 
    367 void WebMediaPlayerClientImpl::seek(double time)
    368 {
    369     if (m_webMediaPlayer)
    370         m_webMediaPlayer->seek(time);
    371 }
    372 
    373 bool WebMediaPlayerClientImpl::seeking() const
    374 {
    375     if (m_webMediaPlayer)
    376         return m_webMediaPlayer->seeking();
    377     return false;
    378 }
    379 
    380 double WebMediaPlayerClientImpl::rate() const
    381 {
    382     return m_rate;
    383 }
    384 
    385 void WebMediaPlayerClientImpl::setRate(double rate)
    386 {
    387     m_rate = rate;
    388     if (m_webMediaPlayer)
    389         m_webMediaPlayer->setRate(rate);
    390 }
    391 
    392 bool WebMediaPlayerClientImpl::paused() const
    393 {
    394     if (m_webMediaPlayer)
    395         return m_webMediaPlayer->paused();
    396     return false;
    397 }
    398 
    399 bool WebMediaPlayerClientImpl::supportsFullscreen() const
    400 {
    401     if (m_webMediaPlayer)
    402         return m_webMediaPlayer->supportsFullscreen();
    403     return false;
    404 }
    405 
    406 bool WebMediaPlayerClientImpl::supportsSave() const
    407 {
    408     if (m_webMediaPlayer)
    409         return m_webMediaPlayer->supportsSave();
    410     return false;
    411 }
    412 
    413 void WebMediaPlayerClientImpl::setVolume(double volume)
    414 {
    415     m_volume = volume;
    416     if (m_webMediaPlayer && !m_muted)
    417         m_webMediaPlayer->setVolume(volume);
    418 }
    419 
    420 void WebMediaPlayerClientImpl::setMuted(bool muted)
    421 {
    422     m_muted = muted;
    423     if (m_webMediaPlayer)
    424         m_webMediaPlayer->setVolume(muted ? 0 : m_volume);
    425 }
    426 
    427 MediaPlayer::NetworkState WebMediaPlayerClientImpl::networkState() const
    428 {
    429     if (m_webMediaPlayer)
    430         return static_cast<MediaPlayer::NetworkState>(m_webMediaPlayer->networkState());
    431     return MediaPlayer::Empty;
    432 }
    433 
    434 MediaPlayer::ReadyState WebMediaPlayerClientImpl::readyState() const
    435 {
    436     if (m_webMediaPlayer)
    437         return static_cast<MediaPlayer::ReadyState>(m_webMediaPlayer->readyState());
    438     return MediaPlayer::HaveNothing;
    439 }
    440 
    441 double WebMediaPlayerClientImpl::maxTimeSeekable() const
    442 {
    443     if (m_webMediaPlayer)
    444         return m_webMediaPlayer->maxTimeSeekable();
    445     return 0.0;
    446 }
    447 
    448 PassRefPtr<TimeRanges> WebMediaPlayerClientImpl::buffered() const
    449 {
    450     if (m_webMediaPlayer)
    451         return TimeRanges::create(m_webMediaPlayer->buffered());
    452     return TimeRanges::create();
    453 }
    454 
    455 bool WebMediaPlayerClientImpl::didLoadingProgress() const
    456 {
    457     return m_webMediaPlayer && m_webMediaPlayer->didLoadingProgress();
    458 }
    459 
    460 void WebMediaPlayerClientImpl::paint(GraphicsContext* context, const IntRect& rect)
    461 {
    462     // Normally GraphicsContext operations do nothing when painting is disabled.
    463     // Since we're accessing platformContext() directly we have to manually
    464     // check.
    465     if (m_webMediaPlayer && !context->paintingDisabled()) {
    466         // On Android, video frame is emitted as GL_TEXTURE_EXTERNAL_OES texture. We use a different path to
    467         // paint the video frame into the context.
    468 #if OS(ANDROID)
    469         if (!m_isMediaStream) {
    470             RefPtr<GraphicsContext3D> context3D = SharedGraphicsContext3D::get();
    471             paintOnAndroid(context, context3D.get(), rect, context->getNormalizedAlpha());
    472             return;
    473         }
    474 #endif
    475         WebCanvas* canvas = context->canvas();
    476         m_webMediaPlayer->paint(canvas, rect, context->getNormalizedAlpha());
    477     }
    478 }
    479 
    480 bool WebMediaPlayerClientImpl::copyVideoTextureToPlatformTexture(WebCore::GraphicsContext3D* context, Platform3DObject texture, GC3Dint level, GC3Denum type, GC3Denum internalFormat, bool premultiplyAlpha, bool flipY)
    481 {
    482     if (!context || !m_webMediaPlayer)
    483         return false;
    484     Extensions3D* extensions = context->extensions();
    485     if (!extensions || !extensions->supports("GL_CHROMIUM_copy_texture") || !extensions->supports("GL_CHROMIUM_flipy")
    486         || !extensions->canUseCopyTextureCHROMIUM(internalFormat, type, level) || !context->makeContextCurrent())
    487         return false;
    488     WebGraphicsContext3D* webGraphicsContext3D = context->webContext();
    489     return m_webMediaPlayer->copyVideoTextureToPlatformTexture(webGraphicsContext3D, texture, level, internalFormat, type, premultiplyAlpha, flipY);
    490 }
    491 
    492 void WebMediaPlayerClientImpl::setPreload(MediaPlayer::Preload preload)
    493 {
    494     m_preload = preload;
    495 
    496     if (m_webMediaPlayer)
    497         m_webMediaPlayer->setPreload(static_cast<WebMediaPlayer::Preload>(preload));
    498 
    499     if (m_delayingLoad && m_preload != MediaPlayer::None)
    500         startDelayedLoad();
    501 }
    502 
    503 bool WebMediaPlayerClientImpl::hasSingleSecurityOrigin() const
    504 {
    505     if (m_webMediaPlayer)
    506         return m_webMediaPlayer->hasSingleSecurityOrigin();
    507     return false;
    508 }
    509 
    510 bool WebMediaPlayerClientImpl::didPassCORSAccessCheck() const
    511 {
    512     if (m_webMediaPlayer)
    513         return m_webMediaPlayer->didPassCORSAccessCheck();
    514     return false;
    515 }
    516 
    517 double WebMediaPlayerClientImpl::mediaTimeForTimeValue(double timeValue) const
    518 {
    519     if (m_webMediaPlayer)
    520         return m_webMediaPlayer->mediaTimeForTimeValue(timeValue);
    521     return timeValue;
    522 }
    523 
    524 unsigned WebMediaPlayerClientImpl::decodedFrameCount() const
    525 {
    526     if (m_webMediaPlayer)
    527         return m_webMediaPlayer->decodedFrameCount();
    528     return 0;
    529 }
    530 
    531 unsigned WebMediaPlayerClientImpl::droppedFrameCount() const
    532 {
    533     if (m_webMediaPlayer)
    534         return m_webMediaPlayer->droppedFrameCount();
    535     return 0;
    536 }
    537 
    538 unsigned WebMediaPlayerClientImpl::corruptedFrameCount() const
    539 {
    540     if (m_webMediaPlayer)
    541         return m_webMediaPlayer->corruptedFrameCount();
    542     return 0;
    543 }
    544 
    545 unsigned WebMediaPlayerClientImpl::audioDecodedByteCount() const
    546 {
    547     if (m_webMediaPlayer)
    548         return m_webMediaPlayer->audioDecodedByteCount();
    549     return 0;
    550 }
    551 
    552 unsigned WebMediaPlayerClientImpl::videoDecodedByteCount() const
    553 {
    554     if (m_webMediaPlayer)
    555         return m_webMediaPlayer->videoDecodedByteCount();
    556     return 0;
    557 }
    558 
    559 #if ENABLE(WEB_AUDIO)
    560 AudioSourceProvider* WebMediaPlayerClientImpl::audioSourceProvider()
    561 {
    562     return &m_audioSourceProvider;
    563 }
    564 #endif
    565 
    566 bool WebMediaPlayerClientImpl::needsWebLayerForVideo() const
    567 {
    568     return m_needsWebLayerForVideo;
    569 }
    570 
    571 PassOwnPtr<MediaPlayer> WebMediaPlayerClientImpl::create(MediaPlayerClient* client)
    572 {
    573     return adoptPtr(new WebMediaPlayerClientImpl(client));
    574 }
    575 
    576 #if OS(ANDROID)
    577 void WebMediaPlayerClientImpl::paintOnAndroid(WebCore::GraphicsContext* context, WebCore::GraphicsContext3D* context3D, const IntRect& rect, uint8_t alpha)
    578 {
    579     if (!context || !context3D || !m_webMediaPlayer || context->paintingDisabled())
    580         return;
    581 
    582     Extensions3D* extensions = context3D->extensions();
    583     if (!extensions || !extensions->supports("GL_CHROMIUM_copy_texture") || !extensions->supports("GL_CHROMIUM_flipy")
    584         || !context3D->makeContextCurrent())
    585         return;
    586 
    587     // Copy video texture into a RGBA texture based bitmap first as video texture on Android is GL_TEXTURE_EXTERNAL_OES
    588     // which is not supported by Skia yet. The bitmap's size needs to be the same as the video and use naturalSize() here.
    589     // Check if we could reuse existing texture based bitmap.
    590     // Otherwise, release existing texture based bitmap and allocate a new one based on video size.
    591     if (!ensureTextureBackedSkBitmap(context3D->grContext(), m_bitmap, naturalSize(), kTopLeft_GrSurfaceOrigin, kSkia8888_GrPixelConfig))
    592         return;
    593 
    594     // Copy video texture to bitmap texture.
    595     WebGraphicsContext3D* webGraphicsContext3D = context3D->webContext();
    596     WebCanvas* canvas = context->canvas();
    597     unsigned textureId = static_cast<unsigned>((m_bitmap.getTexture())->getTextureHandle());
    598     if (!m_webMediaPlayer->copyVideoTextureToPlatformTexture(webGraphicsContext3D, textureId, 0, GL_RGBA, GL_UNSIGNED_BYTE, true, false))
    599         return;
    600 
    601     // Draw the texture based bitmap onto the Canvas. If the canvas is hardware based, this will do a GPU-GPU texture copy. If the canvas is software based,
    602     // the texture based bitmap will be readbacked to system memory then draw onto the canvas.
    603     SkRect dest;
    604     dest.set(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height());
    605     SkPaint paint;
    606     paint.setAlpha(alpha);
    607     // It is not necessary to pass the dest into the drawBitmap call since all the context have been set up before calling paintCurrentFrameInContext.
    608     canvas->drawBitmapRect(m_bitmap, NULL, dest, &paint);
    609 }
    610 #endif
    611 
    612 void WebMediaPlayerClientImpl::startDelayedLoad()
    613 {
    614     ASSERT(m_delayingLoad);
    615     ASSERT(!m_webMediaPlayer);
    616 
    617     m_delayingLoad = false;
    618 
    619     loadInternal();
    620 }
    621 
    622 WebMediaPlayerClientImpl::WebMediaPlayerClientImpl(MediaPlayerClient* client)
    623     : m_client(client)
    624     , m_isMediaStream(false)
    625     , m_delayingLoad(false)
    626     , m_preload(MediaPlayer::Auto)
    627     , m_helperPlugin(0)
    628     , m_needsWebLayerForVideo(false)
    629     , m_volume(1.0)
    630     , m_muted(false)
    631     , m_rate(1.0)
    632 {
    633     ASSERT(m_client);
    634 }
    635 
    636 #if ENABLE(WEB_AUDIO)
    637 void WebMediaPlayerClientImpl::AudioSourceProviderImpl::wrap(WebAudioSourceProvider* provider)
    638 {
    639     MutexLocker locker(provideInputLock);
    640 
    641     if (m_webAudioSourceProvider && provider != m_webAudioSourceProvider)
    642         m_webAudioSourceProvider->setClient(0);
    643 
    644     m_webAudioSourceProvider = provider;
    645     if (m_webAudioSourceProvider)
    646         m_webAudioSourceProvider->setClient(m_client.get());
    647 }
    648 
    649 void WebMediaPlayerClientImpl::AudioSourceProviderImpl::setClient(AudioSourceProviderClient* client)
    650 {
    651     MutexLocker locker(provideInputLock);
    652 
    653     if (client)
    654         m_client = adoptPtr(new WebMediaPlayerClientImpl::AudioClientImpl(client));
    655     else
    656         m_client.clear();
    657 
    658     if (m_webAudioSourceProvider)
    659         m_webAudioSourceProvider->setClient(m_client.get());
    660 }
    661 
    662 void WebMediaPlayerClientImpl::AudioSourceProviderImpl::provideInput(AudioBus* bus, size_t framesToProcess)
    663 {
    664     ASSERT(bus);
    665     if (!bus)
    666         return;
    667 
    668     MutexTryLocker tryLocker(provideInputLock);
    669     if (!tryLocker.locked() || !m_webAudioSourceProvider || !m_client.get()) {
    670         bus->zero();
    671         return;
    672     }
    673 
    674     // Wrap the AudioBus channel data using WebVector.
    675     size_t n = bus->numberOfChannels();
    676     WebVector<float*> webAudioData(n);
    677     for (size_t i = 0; i < n; ++i)
    678         webAudioData[i] = bus->channel(i)->mutableData();
    679 
    680     m_webAudioSourceProvider->provideInput(webAudioData, framesToProcess);
    681 }
    682 
    683 void WebMediaPlayerClientImpl::AudioClientImpl::setFormat(size_t numberOfChannels, float sampleRate)
    684 {
    685     if (m_client)
    686         m_client->setFormat(numberOfChannels, sampleRate);
    687 }
    688 
    689 #endif
    690 
    691 } // namespace blink
    692