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