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 "web/WebMediaPlayerClientImpl.h"
      7 
      8 #include "core/frame/LocalFrame.h"
      9 #include "core/html/HTMLMediaElement.h"
     10 #include "core/html/TimeRanges.h"
     11 #include "core/rendering/RenderView.h"
     12 #include "core/rendering/compositing/RenderLayerCompositor.h"
     13 #include "modules/encryptedmedia/HTMLMediaElementEncryptedMedia.h"
     14 #include "modules/encryptedmedia/MediaKeyNeededEvent.h"
     15 #include "modules/mediastream/MediaStreamRegistry.h"
     16 #include "platform/audio/AudioBus.h"
     17 #include "platform/audio/AudioSourceProviderClient.h"
     18 #include "platform/geometry/IntSize.h"
     19 #include "platform/graphics/GraphicsContext.h"
     20 #include "platform/graphics/GraphicsLayer.h"
     21 #include "platform/graphics/gpu/Extensions3DUtil.h"
     22 #include "platform/graphics/skia/GaneshUtils.h"
     23 #include "public/platform/Platform.h"
     24 #include "public/platform/WebAudioSourceProvider.h"
     25 #include "public/platform/WebCString.h"
     26 #include "public/platform/WebCanvas.h"
     27 #include "public/platform/WebCompositorSupport.h"
     28 #include "public/platform/WebContentDecryptionModule.h"
     29 #include "public/platform/WebGraphicsContext3DProvider.h"
     30 #include "public/platform/WebInbandTextTrack.h"
     31 #include "public/platform/WebMediaPlayer.h"
     32 #include "public/platform/WebRect.h"
     33 #include "public/platform/WebString.h"
     34 #include "public/platform/WebURL.h"
     35 #include "public/web/WebDocument.h"
     36 #include "public/web/WebFrameClient.h"
     37 #include "web/WebLocalFrameImpl.h"
     38 #include "web/WebViewImpl.h"
     39 
     40 #if OS(ANDROID)
     41 #include "GrContext.h"
     42 #include "GrTypes.h"
     43 #include "SkCanvas.h"
     44 #include "SkGrPixelRef.h"
     45 #endif
     46 
     47 
     48 #include "wtf/Assertions.h"
     49 #include "wtf/text/CString.h"
     50 
     51 namespace blink {
     52 
     53 static PassOwnPtr<WebMediaPlayer> createWebMediaPlayer(WebMediaPlayerClient* client, const WebURL& url, LocalFrame* frame, WebContentDecryptionModule* initialCdm)
     54 {
     55     WebLocalFrameImpl* webFrame = WebLocalFrameImpl::fromFrame(frame);
     56 
     57     if (!webFrame || !webFrame->client())
     58         return nullptr;
     59     return adoptPtr(webFrame->client()->createMediaPlayer(webFrame, url, client, initialCdm));
     60 }
     61 
     62 WebMediaPlayer* WebMediaPlayerClientImpl::webMediaPlayer() 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     HTMLMediaElementEncryptedMedia::playerDestroyed(mediaElement());
     75 }
     76 
     77 void WebMediaPlayerClientImpl::networkStateChanged()
     78 {
     79     m_client->mediaPlayerNetworkStateChanged();
     80 }
     81 
     82 void WebMediaPlayerClientImpl::readyStateChanged()
     83 {
     84     m_client->mediaPlayerReadyStateChanged();
     85 }
     86 
     87 void WebMediaPlayerClientImpl::timeChanged()
     88 {
     89     m_client->mediaPlayerTimeChanged();
     90 }
     91 
     92 void WebMediaPlayerClientImpl::repaint()
     93 {
     94     m_client->mediaPlayerRepaint();
     95 }
     96 
     97 void WebMediaPlayerClientImpl::durationChanged()
     98 {
     99     m_client->mediaPlayerDurationChanged();
    100 }
    101 
    102 void WebMediaPlayerClientImpl::sizeChanged()
    103 {
    104     m_client->mediaPlayerSizeChanged();
    105 }
    106 
    107 void WebMediaPlayerClientImpl::playbackStateChanged()
    108 {
    109     m_client->mediaPlayerPlaybackStateChanged();
    110 }
    111 
    112 void WebMediaPlayerClientImpl::keyAdded(const WebString& keySystem, const WebString& sessionId)
    113 {
    114     HTMLMediaElementEncryptedMedia::keyAdded(mediaElement(), keySystem, sessionId);
    115 }
    116 
    117 void WebMediaPlayerClientImpl::keyError(const WebString& keySystem, const WebString& sessionId, MediaKeyErrorCode errorCode, unsigned short systemCode)
    118 {
    119     HTMLMediaElementEncryptedMedia::keyError(mediaElement(), keySystem, sessionId, errorCode, systemCode);
    120 }
    121 
    122 void WebMediaPlayerClientImpl::keyMessage(const WebString& keySystem, const WebString& sessionId, const unsigned char* message, unsigned messageLength, const WebURL& defaultURL)
    123 {
    124     HTMLMediaElementEncryptedMedia::keyMessage(mediaElement(), keySystem, sessionId, message, messageLength, defaultURL);
    125 }
    126 
    127 void WebMediaPlayerClientImpl::keyNeeded(const WebString& contentType, const unsigned char* initData, unsigned initDataLength)
    128 {
    129     HTMLMediaElementEncryptedMedia::keyNeeded(mediaElement(), contentType, initData, initDataLength);
    130 }
    131 
    132 void WebMediaPlayerClientImpl::setWebLayer(WebLayer* layer)
    133 {
    134     m_client->mediaPlayerSetWebLayer(layer);
    135 }
    136 
    137 WebMediaPlayer::TrackId WebMediaPlayerClientImpl::addAudioTrack(const WebString& id, AudioTrackKind kind, const WebString& label, const WebString& language, bool enabled)
    138 {
    139     return mediaElement().addAudioTrack(id, kind, label, language, enabled);
    140 }
    141 
    142 void WebMediaPlayerClientImpl::removeAudioTrack(WebMediaPlayer::TrackId id)
    143 {
    144     mediaElement().removeAudioTrack(id);
    145 }
    146 
    147 WebMediaPlayer::TrackId WebMediaPlayerClientImpl::addVideoTrack(const WebString& id, VideoTrackKind kind, const WebString& label, const WebString& language, bool selected)
    148 {
    149     return mediaElement().addVideoTrack(id, kind, label, language, selected);
    150 }
    151 
    152 void WebMediaPlayerClientImpl::removeVideoTrack(WebMediaPlayer::TrackId id)
    153 {
    154     mediaElement().removeVideoTrack(id);
    155 }
    156 
    157 void WebMediaPlayerClientImpl::addTextTrack(WebInbandTextTrack* textTrack)
    158 {
    159     m_client->mediaPlayerDidAddTextTrack(textTrack);
    160 }
    161 
    162 void WebMediaPlayerClientImpl::removeTextTrack(WebInbandTextTrack* textTrack)
    163 {
    164     m_client->mediaPlayerDidRemoveTextTrack(textTrack);
    165 }
    166 
    167 void WebMediaPlayerClientImpl::mediaSourceOpened(WebMediaSource* webMediaSource)
    168 {
    169     ASSERT(webMediaSource);
    170     m_client->mediaPlayerMediaSourceOpened(webMediaSource);
    171 }
    172 
    173 void WebMediaPlayerClientImpl::requestFullscreen()
    174 {
    175     m_client->mediaPlayerRequestFullscreen();
    176 }
    177 
    178 void WebMediaPlayerClientImpl::requestSeek(double time)
    179 {
    180     m_client->mediaPlayerRequestSeek(time);
    181 }
    182 
    183 void WebMediaPlayerClientImpl::remoteRouteAvailabilityChanged(bool routesAvailable)
    184 {
    185     mediaElement().remoteRouteAvailabilityChanged(routesAvailable);
    186 }
    187 
    188 void WebMediaPlayerClientImpl::connectedToRemoteDevice()
    189 {
    190     mediaElement().connectedToRemoteDevice();
    191 }
    192 
    193 void WebMediaPlayerClientImpl::disconnectedFromRemoteDevice()
    194 {
    195     mediaElement().disconnectedFromRemoteDevice();
    196 }
    197 
    198 // MediaPlayer -------------------------------------------------
    199 void WebMediaPlayerClientImpl::load(WebMediaPlayer::LoadType loadType, const WTF::String& url, WebMediaPlayer::CORSMode corsMode)
    200 {
    201     ASSERT(!m_webMediaPlayer);
    202 
    203     // FIXME: Remove this cast
    204     LocalFrame* frame = mediaElement().document().frame();
    205 
    206     WebURL poster = m_client->mediaPlayerPosterURL();
    207 
    208     KURL kurl(ParsedURLString, url);
    209     m_webMediaPlayer = createWebMediaPlayer(this, kurl, frame, HTMLMediaElementEncryptedMedia::contentDecryptionModule(mediaElement()));
    210     if (!m_webMediaPlayer)
    211         return;
    212 
    213 #if ENABLE(WEB_AUDIO)
    214     // Make sure if we create/re-create the WebMediaPlayer that we update our wrapper.
    215     m_audioSourceProvider.wrap(m_webMediaPlayer->audioSourceProvider());
    216 #endif
    217 
    218     m_webMediaPlayer->setVolume(mediaElement().effectiveMediaVolume());
    219 
    220     m_webMediaPlayer->setPoster(poster);
    221 
    222     m_webMediaPlayer->load(loadType, kurl, corsMode);
    223 }
    224 
    225 void WebMediaPlayerClientImpl::setPreload(MediaPlayer::Preload preload)
    226 {
    227     if (m_webMediaPlayer)
    228         m_webMediaPlayer->setPreload(static_cast<WebMediaPlayer::Preload>(preload));
    229 }
    230 
    231 #if ENABLE(WEB_AUDIO)
    232 AudioSourceProvider* WebMediaPlayerClientImpl::audioSourceProvider()
    233 {
    234     return &m_audioSourceProvider;
    235 }
    236 #endif
    237 
    238 PassOwnPtr<MediaPlayer> WebMediaPlayerClientImpl::create(MediaPlayerClient* client)
    239 {
    240     return adoptPtr(new WebMediaPlayerClientImpl(client));
    241 }
    242 
    243 WebMediaPlayerClientImpl::WebMediaPlayerClientImpl(MediaPlayerClient* client)
    244     : m_client(client)
    245 {
    246     ASSERT(m_client);
    247 }
    248 
    249 HTMLMediaElement& WebMediaPlayerClientImpl::mediaElement() const
    250 {
    251     return *static_cast<HTMLMediaElement*>(m_client);
    252 }
    253 
    254 #if ENABLE(WEB_AUDIO)
    255 void WebMediaPlayerClientImpl::AudioSourceProviderImpl::wrap(WebAudioSourceProvider* provider)
    256 {
    257     MutexLocker locker(provideInputLock);
    258 
    259     if (m_webAudioSourceProvider && provider != m_webAudioSourceProvider)
    260         m_webAudioSourceProvider->setClient(0);
    261 
    262     m_webAudioSourceProvider = provider;
    263     if (m_webAudioSourceProvider)
    264         m_webAudioSourceProvider->setClient(m_client.get());
    265 }
    266 
    267 void WebMediaPlayerClientImpl::AudioSourceProviderImpl::setClient(AudioSourceProviderClient* client)
    268 {
    269     MutexLocker locker(provideInputLock);
    270 
    271     if (client)
    272         m_client = new WebMediaPlayerClientImpl::AudioClientImpl(client);
    273     else
    274         m_client.clear();
    275 
    276     if (m_webAudioSourceProvider)
    277         m_webAudioSourceProvider->setClient(m_client.get());
    278 }
    279 
    280 void WebMediaPlayerClientImpl::AudioSourceProviderImpl::provideInput(AudioBus* bus, size_t framesToProcess)
    281 {
    282     ASSERT(bus);
    283     if (!bus)
    284         return;
    285 
    286     MutexTryLocker tryLocker(provideInputLock);
    287     if (!tryLocker.locked() || !m_webAudioSourceProvider || !m_client.get()) {
    288         bus->zero();
    289         return;
    290     }
    291 
    292     // Wrap the AudioBus channel data using WebVector.
    293     size_t n = bus->numberOfChannels();
    294     WebVector<float*> webAudioData(n);
    295     for (size_t i = 0; i < n; ++i)
    296         webAudioData[i] = bus->channel(i)->mutableData();
    297 
    298     m_webAudioSourceProvider->provideInput(webAudioData, framesToProcess);
    299 }
    300 
    301 void WebMediaPlayerClientImpl::AudioClientImpl::setFormat(size_t numberOfChannels, float sampleRate)
    302 {
    303     if (m_client)
    304         m_client->setFormat(numberOfChannels, sampleRate);
    305 }
    306 
    307 void WebMediaPlayerClientImpl::AudioClientImpl::trace(Visitor* visitor)
    308 {
    309     visitor->trace(m_client);
    310 }
    311 
    312 #endif
    313 
    314 } // namespace blink
    315