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
createWebMediaPlayer(WebMediaPlayerClient * client,const WebURL & url,LocalFrame * frame,WebContentDecryptionModule * initialCdm)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
webMediaPlayer() const62 WebMediaPlayer* WebMediaPlayerClientImpl::webMediaPlayer() const
63 {
64 return m_webMediaPlayer.get();
65 }
66
67 // WebMediaPlayerClient --------------------------------------------------------
68
~WebMediaPlayerClientImpl()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
networkStateChanged()77 void WebMediaPlayerClientImpl::networkStateChanged()
78 {
79 m_client->mediaPlayerNetworkStateChanged();
80 }
81
readyStateChanged()82 void WebMediaPlayerClientImpl::readyStateChanged()
83 {
84 m_client->mediaPlayerReadyStateChanged();
85 }
86
timeChanged()87 void WebMediaPlayerClientImpl::timeChanged()
88 {
89 m_client->mediaPlayerTimeChanged();
90 }
91
repaint()92 void WebMediaPlayerClientImpl::repaint()
93 {
94 m_client->mediaPlayerRepaint();
95 }
96
durationChanged()97 void WebMediaPlayerClientImpl::durationChanged()
98 {
99 m_client->mediaPlayerDurationChanged();
100 }
101
sizeChanged()102 void WebMediaPlayerClientImpl::sizeChanged()
103 {
104 m_client->mediaPlayerSizeChanged();
105 }
106
playbackStateChanged()107 void WebMediaPlayerClientImpl::playbackStateChanged()
108 {
109 m_client->mediaPlayerPlaybackStateChanged();
110 }
111
keyAdded(const WebString & keySystem,const WebString & sessionId)112 void WebMediaPlayerClientImpl::keyAdded(const WebString& keySystem, const WebString& sessionId)
113 {
114 HTMLMediaElementEncryptedMedia::keyAdded(mediaElement(), keySystem, sessionId);
115 }
116
keyError(const WebString & keySystem,const WebString & sessionId,MediaKeyErrorCode errorCode,unsigned short systemCode)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
keyMessage(const WebString & keySystem,const WebString & sessionId,const unsigned char * message,unsigned messageLength,const WebURL & defaultURL)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
keyNeeded(const WebString & contentType,const unsigned char * initData,unsigned initDataLength)127 void WebMediaPlayerClientImpl::keyNeeded(const WebString& contentType, const unsigned char* initData, unsigned initDataLength)
128 {
129 HTMLMediaElementEncryptedMedia::keyNeeded(mediaElement(), contentType, initData, initDataLength);
130 }
131
setWebLayer(WebLayer * layer)132 void WebMediaPlayerClientImpl::setWebLayer(WebLayer* layer)
133 {
134 m_client->mediaPlayerSetWebLayer(layer);
135 }
136
addAudioTrack(const WebString & id,AudioTrackKind kind,const WebString & label,const WebString & language,bool enabled)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
removeAudioTrack(WebMediaPlayer::TrackId id)142 void WebMediaPlayerClientImpl::removeAudioTrack(WebMediaPlayer::TrackId id)
143 {
144 mediaElement().removeAudioTrack(id);
145 }
146
addVideoTrack(const WebString & id,VideoTrackKind kind,const WebString & label,const WebString & language,bool selected)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
removeVideoTrack(WebMediaPlayer::TrackId id)152 void WebMediaPlayerClientImpl::removeVideoTrack(WebMediaPlayer::TrackId id)
153 {
154 mediaElement().removeVideoTrack(id);
155 }
156
addTextTrack(WebInbandTextTrack * textTrack)157 void WebMediaPlayerClientImpl::addTextTrack(WebInbandTextTrack* textTrack)
158 {
159 m_client->mediaPlayerDidAddTextTrack(textTrack);
160 }
161
removeTextTrack(WebInbandTextTrack * textTrack)162 void WebMediaPlayerClientImpl::removeTextTrack(WebInbandTextTrack* textTrack)
163 {
164 m_client->mediaPlayerDidRemoveTextTrack(textTrack);
165 }
166
mediaSourceOpened(WebMediaSource * webMediaSource)167 void WebMediaPlayerClientImpl::mediaSourceOpened(WebMediaSource* webMediaSource)
168 {
169 ASSERT(webMediaSource);
170 m_client->mediaPlayerMediaSourceOpened(webMediaSource);
171 }
172
requestFullscreen()173 void WebMediaPlayerClientImpl::requestFullscreen()
174 {
175 m_client->mediaPlayerRequestFullscreen();
176 }
177
requestSeek(double time)178 void WebMediaPlayerClientImpl::requestSeek(double time)
179 {
180 m_client->mediaPlayerRequestSeek(time);
181 }
182
remoteRouteAvailabilityChanged(bool routesAvailable)183 void WebMediaPlayerClientImpl::remoteRouteAvailabilityChanged(bool routesAvailable)
184 {
185 mediaElement().remoteRouteAvailabilityChanged(routesAvailable);
186 }
187
connectedToRemoteDevice()188 void WebMediaPlayerClientImpl::connectedToRemoteDevice()
189 {
190 mediaElement().connectedToRemoteDevice();
191 }
192
disconnectedFromRemoteDevice()193 void WebMediaPlayerClientImpl::disconnectedFromRemoteDevice()
194 {
195 mediaElement().disconnectedFromRemoteDevice();
196 }
197
198 // MediaPlayer -------------------------------------------------
load(WebMediaPlayer::LoadType loadType,const WTF::String & url,WebMediaPlayer::CORSMode corsMode)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
setPreload(MediaPlayer::Preload preload)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)
audioSourceProvider()232 AudioSourceProvider* WebMediaPlayerClientImpl::audioSourceProvider()
233 {
234 return &m_audioSourceProvider;
235 }
236 #endif
237
create(MediaPlayerClient * client)238 PassOwnPtr<MediaPlayer> WebMediaPlayerClientImpl::create(MediaPlayerClient* client)
239 {
240 return adoptPtr(new WebMediaPlayerClientImpl(client));
241 }
242
WebMediaPlayerClientImpl(MediaPlayerClient * client)243 WebMediaPlayerClientImpl::WebMediaPlayerClientImpl(MediaPlayerClient* client)
244 : m_client(client)
245 {
246 ASSERT(m_client);
247 }
248
mediaElement() const249 HTMLMediaElement& WebMediaPlayerClientImpl::mediaElement() const
250 {
251 return *static_cast<HTMLMediaElement*>(m_client);
252 }
253
254 #if ENABLE(WEB_AUDIO)
wrap(WebAudioSourceProvider * provider)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
setClient(AudioSourceProviderClient * client)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
provideInput(AudioBus * bus,size_t framesToProcess)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
setFormat(size_t numberOfChannels,float sampleRate)301 void WebMediaPlayerClientImpl::AudioClientImpl::setFormat(size_t numberOfChannels, float sampleRate)
302 {
303 if (m_client)
304 m_client->setFormat(numberOfChannels, sampleRate);
305 }
306
trace(Visitor * visitor)307 void WebMediaPlayerClientImpl::AudioClientImpl::trace(Visitor* visitor)
308 {
309 visitor->trace(m_client);
310 }
311
312 #endif
313
314 } // namespace blink
315