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