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