• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
createWebMediaPlayer(WebMediaPlayerClient * client,const WebURL & url,Frame * frame)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 
mediaPlayer() const62 WebMediaPlayer* WebMediaPlayerClientImpl::mediaPlayer() 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     // Ensure the m_webMediaPlayer destroyed any WebHelperPlugin used.
75     ASSERT(!m_helperPlugin);
76 }
77 
networkStateChanged()78 void WebMediaPlayerClientImpl::networkStateChanged()
79 {
80     m_client->mediaPlayerNetworkStateChanged();
81 }
82 
readyStateChanged()83 void WebMediaPlayerClientImpl::readyStateChanged()
84 {
85     m_client->mediaPlayerReadyStateChanged();
86 }
87 
timeChanged()88 void WebMediaPlayerClientImpl::timeChanged()
89 {
90     m_client->mediaPlayerTimeChanged();
91 }
92 
repaint()93 void WebMediaPlayerClientImpl::repaint()
94 {
95     m_client->mediaPlayerRepaint();
96 }
97 
durationChanged()98 void WebMediaPlayerClientImpl::durationChanged()
99 {
100     m_client->mediaPlayerDurationChanged();
101 }
102 
sizeChanged()103 void WebMediaPlayerClientImpl::sizeChanged()
104 {
105     m_client->mediaPlayerSizeChanged();
106 }
107 
setOpaque(bool opaque)108 void WebMediaPlayerClientImpl::setOpaque(bool opaque)
109 {
110     m_client->mediaPlayerSetOpaque(opaque);
111 }
112 
volume() const113 double WebMediaPlayerClientImpl::volume() const
114 {
115     return m_volume;
116 }
117 
playbackStateChanged()118 void WebMediaPlayerClientImpl::playbackStateChanged()
119 {
120     m_client->mediaPlayerPlaybackStateChanged();
121 }
122 
preload() const123 WebMediaPlayer::Preload WebMediaPlayerClientImpl::preload() const
124 {
125     return static_cast<WebMediaPlayer::Preload>(m_preload);
126 }
127 
keyAdded(const WebString & keySystem,const WebString & sessionId)128 void WebMediaPlayerClientImpl::keyAdded(const WebString& keySystem, const WebString& sessionId)
129 {
130     m_client->mediaPlayerKeyAdded(keySystem, sessionId);
131 }
132 
keyError(const WebString & keySystem,const WebString & sessionId,MediaKeyErrorCode errorCode,unsigned short systemCode)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 
keyMessage(const WebString & keySystem,const WebString & sessionId,const unsigned char * message,unsigned messageLength,const WebURL & defaultURL)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 
keyNeeded(const WebString & keySystem,const WebString & sessionId,const unsigned char * initData,unsigned initDataLength)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 
createHelperPlugin(const WebString & pluginType,WebFrame * frame)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 
closeHelperPluginSoon(WebFrame * frame)168 void WebMediaPlayerClientImpl::closeHelperPluginSoon(WebFrame* frame)
169 {
170     ASSERT(m_helperPlugin);
171     toWebViewImpl(frame->view())->closeHelperPluginSoon(m_helperPlugin.release());
172 }
173 
setWebLayer(blink::WebLayer * layer)174 void WebMediaPlayerClientImpl::setWebLayer(blink::WebLayer* layer)
175 {
176     m_client->mediaPlayerSetWebLayer(layer);
177 }
178 
addTextTrack(WebInbandTextTrack * textTrack)179 void WebMediaPlayerClientImpl::addTextTrack(WebInbandTextTrack* textTrack)
180 {
181     m_client->mediaPlayerDidAddTrack(textTrack);
182 }
183 
removeTextTrack(WebInbandTextTrack * textTrack)184 void WebMediaPlayerClientImpl::removeTextTrack(WebInbandTextTrack* textTrack)
185 {
186     m_client->mediaPlayerDidRemoveTrack(textTrack);
187 }
188 
mediaSourceOpened(WebMediaSource * webMediaSource)189 void WebMediaPlayerClientImpl::mediaSourceOpened(WebMediaSource* webMediaSource)
190 {
191     ASSERT(webMediaSource);
192     m_mediaSource->setWebMediaSourceAndOpen(adoptPtr(webMediaSource));
193     m_mediaSource = 0;
194 }
195 
requestFullscreen()196 void WebMediaPlayerClientImpl::requestFullscreen()
197 {
198     m_client->mediaPlayerRequestFullscreen();
199 }
200 
requestSeek(double time)201 void WebMediaPlayerClientImpl::requestSeek(double time)
202 {
203     m_client->mediaPlayerRequestSeek(time);
204 }
205 
206 // MediaPlayer -------------------------------------------------
207 
load(const String & url)208 void WebMediaPlayerClientImpl::load(const String& url)
209 {
210     m_url = KURL(ParsedURLString, url);
211     m_mediaSource = 0;
212     loadRequested();
213 }
214 
load(const String & url,PassRefPtr<WebCore::HTMLMediaSource> mediaSource)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 
loadRequested()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 
loadInternal()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 
play()270 void WebMediaPlayerClientImpl::play()
271 {
272     if (m_webMediaPlayer)
273         m_webMediaPlayer->play();
274 }
275 
pause()276 void WebMediaPlayerClientImpl::pause()
277 {
278     if (m_webMediaPlayer)
279         m_webMediaPlayer->pause();
280 }
281 
showFullscreenOverlay()282 void WebMediaPlayerClientImpl::showFullscreenOverlay()
283 {
284     if (m_webMediaPlayer)
285         m_webMediaPlayer->enterFullscreen();
286 }
287 
hideFullscreenOverlay()288 void WebMediaPlayerClientImpl::hideFullscreenOverlay()
289 {
290     if (m_webMediaPlayer)
291         m_webMediaPlayer->exitFullscreen();
292 }
293 
canShowFullscreenOverlay() const294 bool WebMediaPlayerClientImpl::canShowFullscreenOverlay() const
295 {
296     return m_webMediaPlayer && m_webMediaPlayer->canEnterFullscreen();
297 }
298 
generateKeyRequest(const String & keySystem,const unsigned char * initData,unsigned initDataLength)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 
addKey(const String & keySystem,const unsigned char * key,unsigned keyLength,const unsigned char * initData,unsigned initDataLength,const String & sessionId)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 
cancelKeyRequest(const String & keySystem,const String & sessionId)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 
prepareToPlay()326 void WebMediaPlayerClientImpl::prepareToPlay()
327 {
328     if (m_delayingLoad)
329         startDelayedLoad();
330 }
331 
naturalSize() const332 IntSize WebMediaPlayerClientImpl::naturalSize() const
333 {
334     if (m_webMediaPlayer)
335         return m_webMediaPlayer->naturalSize();
336     return IntSize();
337 }
338 
hasVideo() const339 bool WebMediaPlayerClientImpl::hasVideo() const
340 {
341     if (m_webMediaPlayer)
342         return m_webMediaPlayer->hasVideo();
343     return false;
344 }
345 
hasAudio() const346 bool WebMediaPlayerClientImpl::hasAudio() const
347 {
348     if (m_webMediaPlayer)
349         return m_webMediaPlayer->hasAudio();
350     return false;
351 }
352 
duration() const353 double WebMediaPlayerClientImpl::duration() const
354 {
355     if (m_webMediaPlayer)
356         return m_webMediaPlayer->duration();
357     return 0.0;
358 }
359 
currentTime() const360 double WebMediaPlayerClientImpl::currentTime() const
361 {
362     if (m_webMediaPlayer)
363         return m_webMediaPlayer->currentTime();
364     return 0.0;
365 }
366 
seek(double time)367 void WebMediaPlayerClientImpl::seek(double time)
368 {
369     if (m_webMediaPlayer)
370         m_webMediaPlayer->seek(time);
371 }
372 
seeking() const373 bool WebMediaPlayerClientImpl::seeking() const
374 {
375     if (m_webMediaPlayer)
376         return m_webMediaPlayer->seeking();
377     return false;
378 }
379 
rate() const380 double WebMediaPlayerClientImpl::rate() const
381 {
382     return m_rate;
383 }
384 
setRate(double rate)385 void WebMediaPlayerClientImpl::setRate(double rate)
386 {
387     m_rate = rate;
388     if (m_webMediaPlayer)
389         m_webMediaPlayer->setRate(rate);
390 }
391 
paused() const392 bool WebMediaPlayerClientImpl::paused() const
393 {
394     if (m_webMediaPlayer)
395         return m_webMediaPlayer->paused();
396     return false;
397 }
398 
supportsFullscreen() const399 bool WebMediaPlayerClientImpl::supportsFullscreen() const
400 {
401     if (m_webMediaPlayer)
402         return m_webMediaPlayer->supportsFullscreen();
403     return false;
404 }
405 
supportsSave() const406 bool WebMediaPlayerClientImpl::supportsSave() const
407 {
408     if (m_webMediaPlayer)
409         return m_webMediaPlayer->supportsSave();
410     return false;
411 }
412 
setVolume(double volume)413 void WebMediaPlayerClientImpl::setVolume(double volume)
414 {
415     m_volume = volume;
416     if (m_webMediaPlayer && !m_muted)
417         m_webMediaPlayer->setVolume(volume);
418 }
419 
setMuted(bool muted)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 
networkState() const427 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 
readyState() const434 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 
maxTimeSeekable() const441 double WebMediaPlayerClientImpl::maxTimeSeekable() const
442 {
443     if (m_webMediaPlayer)
444         return m_webMediaPlayer->maxTimeSeekable();
445     return 0.0;
446 }
447 
buffered() const448 PassRefPtr<TimeRanges> WebMediaPlayerClientImpl::buffered() const
449 {
450     if (m_webMediaPlayer)
451         return TimeRanges::create(m_webMediaPlayer->buffered());
452     return TimeRanges::create();
453 }
454 
didLoadingProgress() const455 bool WebMediaPlayerClientImpl::didLoadingProgress() const
456 {
457     return m_webMediaPlayer && m_webMediaPlayer->didLoadingProgress();
458 }
459 
paint(GraphicsContext * context,const IntRect & rect)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 
copyVideoTextureToPlatformTexture(WebCore::GraphicsContext3D * context,Platform3DObject texture,GC3Dint level,GC3Denum type,GC3Denum internalFormat,bool premultiplyAlpha,bool flipY)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 
setPreload(MediaPlayer::Preload preload)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 
hasSingleSecurityOrigin() const503 bool WebMediaPlayerClientImpl::hasSingleSecurityOrigin() const
504 {
505     if (m_webMediaPlayer)
506         return m_webMediaPlayer->hasSingleSecurityOrigin();
507     return false;
508 }
509 
didPassCORSAccessCheck() const510 bool WebMediaPlayerClientImpl::didPassCORSAccessCheck() const
511 {
512     if (m_webMediaPlayer)
513         return m_webMediaPlayer->didPassCORSAccessCheck();
514     return false;
515 }
516 
mediaTimeForTimeValue(double timeValue) const517 double WebMediaPlayerClientImpl::mediaTimeForTimeValue(double timeValue) const
518 {
519     if (m_webMediaPlayer)
520         return m_webMediaPlayer->mediaTimeForTimeValue(timeValue);
521     return timeValue;
522 }
523 
decodedFrameCount() const524 unsigned WebMediaPlayerClientImpl::decodedFrameCount() const
525 {
526     if (m_webMediaPlayer)
527         return m_webMediaPlayer->decodedFrameCount();
528     return 0;
529 }
530 
droppedFrameCount() const531 unsigned WebMediaPlayerClientImpl::droppedFrameCount() const
532 {
533     if (m_webMediaPlayer)
534         return m_webMediaPlayer->droppedFrameCount();
535     return 0;
536 }
537 
corruptedFrameCount() const538 unsigned WebMediaPlayerClientImpl::corruptedFrameCount() const
539 {
540     if (m_webMediaPlayer)
541         return m_webMediaPlayer->corruptedFrameCount();
542     return 0;
543 }
544 
audioDecodedByteCount() const545 unsigned WebMediaPlayerClientImpl::audioDecodedByteCount() const
546 {
547     if (m_webMediaPlayer)
548         return m_webMediaPlayer->audioDecodedByteCount();
549     return 0;
550 }
551 
videoDecodedByteCount() const552 unsigned WebMediaPlayerClientImpl::videoDecodedByteCount() const
553 {
554     if (m_webMediaPlayer)
555         return m_webMediaPlayer->videoDecodedByteCount();
556     return 0;
557 }
558 
559 #if ENABLE(WEB_AUDIO)
audioSourceProvider()560 AudioSourceProvider* WebMediaPlayerClientImpl::audioSourceProvider()
561 {
562     return &m_audioSourceProvider;
563 }
564 #endif
565 
needsWebLayerForVideo() const566 bool WebMediaPlayerClientImpl::needsWebLayerForVideo() const
567 {
568     return m_needsWebLayerForVideo;
569 }
570 
create(MediaPlayerClient * client)571 PassOwnPtr<MediaPlayer> WebMediaPlayerClientImpl::create(MediaPlayerClient* client)
572 {
573     return adoptPtr(new WebMediaPlayerClientImpl(client));
574 }
575 
576 #if OS(ANDROID)
paintOnAndroid(WebCore::GraphicsContext * context,WebCore::GraphicsContext3D * context3D,const IntRect & rect,uint8_t alpha)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 
startDelayedLoad()612 void WebMediaPlayerClientImpl::startDelayedLoad()
613 {
614     ASSERT(m_delayingLoad);
615     ASSERT(!m_webMediaPlayer);
616 
617     m_delayingLoad = false;
618 
619     loadInternal();
620 }
621 
WebMediaPlayerClientImpl(MediaPlayerClient * client)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)
wrap(WebAudioSourceProvider * provider)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 
setClient(AudioSourceProviderClient * client)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 
provideInput(AudioBus * bus,size_t framesToProcess)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 
setFormat(size_t numberOfChannels,float sampleRate)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