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.
6 #include "WebMediaPlayerClientImpl.h"
11 #include "GraphicsContext.h"
12 #include "HTMLMediaElement.h"
15 #include "MediaPlayer.h"
16 #include "NotImplemented.h"
17 #include "RenderView.h"
18 #include "TimeRanges.h"
19 #include "VideoLayerChromium.h"
21 #if USE(ACCELERATED_COMPOSITING)
22 #include "RenderLayerCompositor.h"
25 #include "VideoFrameChromium.h"
26 #include "VideoFrameChromiumImpl.h"
27 #include "WebAudioSourceProvider.h"
28 #include "WebCanvas.h"
29 #include "WebCString.h"
30 #include "WebFrameClient.h"
31 #include "WebFrameImpl.h"
33 #include "WebKitPlatformSupport.h"
34 #include "WebMediaElement.h"
35 #include "WebMediaPlayer.h"
36 #include "WebMimeRegistry.h"
39 #include "WebString.h"
41 #include "WebViewImpl.h"
43 // WebCommon.h defines WEBKIT_USING_SKIA so this has to be included last.
45 #include "PlatformContextSkia.h"
48 #include <wtf/Assertions.h>
49 #include <wtf/text/CString.h>
51 using namespace WebCore;
55 static PassOwnPtr<WebMediaPlayer> createWebMediaPlayer(WebMediaPlayerClient* client, Frame* frame)
57 WebFrameImpl* webFrame = WebFrameImpl::fromFrame(frame);
59 if (!webFrame->client())
61 return adoptPtr(webFrame->client()->createMediaPlayer(webFrame, client));
64 bool WebMediaPlayerClientImpl::m_isEnabled = false;
66 bool WebMediaPlayerClientImpl::isEnabled()
71 void WebMediaPlayerClientImpl::setIsEnabled(bool isEnabled)
73 m_isEnabled = isEnabled;
76 void WebMediaPlayerClientImpl::registerSelf(MediaEngineRegistrar registrar)
79 registrar(WebMediaPlayerClientImpl::create,
80 WebMediaPlayerClientImpl::getSupportedTypes,
81 WebMediaPlayerClientImpl::supportsType,
88 WebMediaPlayerClientImpl* WebMediaPlayerClientImpl::fromMediaElement(const WebMediaElement* element)
90 PlatformMedia pm = element->constUnwrap<HTMLMediaElement>()->platformMedia();
91 return static_cast<WebMediaPlayerClientImpl*>(pm.media.chromiumMediaPlayer);
94 WebMediaPlayer* WebMediaPlayerClientImpl::mediaPlayer() const
96 return m_webMediaPlayer.get();
99 // WebMediaPlayerClient --------------------------------------------------------
101 WebMediaPlayerClientImpl::~WebMediaPlayerClientImpl()
103 // VideoLayerChromium may outlive this object so make sure all frames are
105 #if USE(ACCELERATED_COMPOSITING)
106 if (m_videoLayer.get())
107 m_videoLayer->releaseCurrentFrame();
111 void WebMediaPlayerClientImpl::networkStateChanged()
113 ASSERT(m_mediaPlayer);
114 m_mediaPlayer->networkStateChanged();
117 void WebMediaPlayerClientImpl::readyStateChanged()
119 ASSERT(m_mediaPlayer);
120 m_mediaPlayer->readyStateChanged();
121 #if USE(ACCELERATED_COMPOSITING)
122 if (hasVideo() && supportsAcceleratedRendering() && !m_videoLayer.get())
123 m_videoLayer = VideoLayerChromium::create(0, this);
127 void WebMediaPlayerClientImpl::volumeChanged(float newVolume)
129 ASSERT(m_mediaPlayer);
130 m_mediaPlayer->volumeChanged(newVolume);
133 void WebMediaPlayerClientImpl::muteChanged(bool newMute)
135 ASSERT(m_mediaPlayer);
136 m_mediaPlayer->muteChanged(newMute);
139 void WebMediaPlayerClientImpl::timeChanged()
141 ASSERT(m_mediaPlayer);
142 m_mediaPlayer->timeChanged();
145 void WebMediaPlayerClientImpl::repaint()
147 ASSERT(m_mediaPlayer);
148 #if USE(ACCELERATED_COMPOSITING)
149 if (m_videoLayer.get() && supportsAcceleratedRendering())
150 m_videoLayer->setNeedsDisplay(IntRect(0, 0, m_videoLayer->bounds().width(), m_videoLayer->bounds().height()));
152 m_mediaPlayer->repaint();
155 void WebMediaPlayerClientImpl::durationChanged()
157 ASSERT(m_mediaPlayer);
158 m_mediaPlayer->durationChanged();
161 void WebMediaPlayerClientImpl::rateChanged()
163 ASSERT(m_mediaPlayer);
164 m_mediaPlayer->rateChanged();
167 void WebMediaPlayerClientImpl::sizeChanged()
169 ASSERT(m_mediaPlayer);
170 m_mediaPlayer->sizeChanged();
173 void WebMediaPlayerClientImpl::sawUnsupportedTracks()
175 ASSERT(m_mediaPlayer);
176 m_mediaPlayer->mediaPlayerClient()->mediaPlayerSawUnsupportedTracks(m_mediaPlayer);
179 float WebMediaPlayerClientImpl::volume() const
182 return m_mediaPlayer->volume();
186 void WebMediaPlayerClientImpl::playbackStateChanged()
188 ASSERT(m_mediaPlayer);
189 m_mediaPlayer->playbackStateChanged();
192 WebMediaPlayer::Preload WebMediaPlayerClientImpl::preload() const
195 return static_cast<WebMediaPlayer::Preload>(m_mediaPlayer->preload());
196 return static_cast<WebMediaPlayer::Preload>(m_preload);
199 void WebMediaPlayerClientImpl::sourceOpened()
201 #if ENABLE(MEDIA_SOURCE)
202 ASSERT(m_mediaPlayer);
203 m_mediaPlayer->sourceOpened();
207 WebKit::WebURL WebMediaPlayerClientImpl::sourceURL() const
209 #if ENABLE(MEDIA_SOURCE)
210 ASSERT(m_mediaPlayer);
211 return KURL(ParsedURLString, m_mediaPlayer->sourceURL());
217 // MediaPlayerPrivateInterface -------------------------------------------------
219 void WebMediaPlayerClientImpl::load(const String& url)
223 // Video frame object is owned by WebMediaPlayer. Before destroying
224 // WebMediaPlayer all frames need to be released.
225 #if USE(ACCELERATED_COMPOSITING)
226 if (m_videoLayer.get())
227 m_videoLayer->releaseCurrentFrame();
230 if (m_preload == MediaPlayer::None) {
231 m_webMediaPlayer.clear();
232 m_delayingLoad = true;
237 void WebMediaPlayerClientImpl::loadInternal()
239 Frame* frame = static_cast<HTMLMediaElement*>(m_mediaPlayer->mediaPlayerClient())->document()->frame();
240 m_webMediaPlayer = createWebMediaPlayer(this, frame);
241 if (m_webMediaPlayer.get())
242 m_webMediaPlayer->load(KURL(ParsedURLString, m_url));
245 void WebMediaPlayerClientImpl::cancelLoad()
247 if (m_webMediaPlayer.get())
248 m_webMediaPlayer->cancelLoad();
251 #if USE(ACCELERATED_COMPOSITING)
252 PlatformLayer* WebMediaPlayerClientImpl::platformLayer() const
254 ASSERT(m_supportsAcceleratedCompositing);
255 return m_videoLayer.get();
259 PlatformMedia WebMediaPlayerClientImpl::platformMedia() const
262 pm.type = PlatformMedia::ChromiumMediaPlayerType;
263 pm.media.chromiumMediaPlayer = const_cast<WebMediaPlayerClientImpl*>(this);
267 void WebMediaPlayerClientImpl::play()
269 if (m_webMediaPlayer.get())
270 m_webMediaPlayer->play();
273 void WebMediaPlayerClientImpl::pause()
275 if (m_webMediaPlayer.get())
276 m_webMediaPlayer->pause();
279 #if ENABLE(MEDIA_SOURCE)
280 bool WebMediaPlayerClientImpl::sourceAppend(const unsigned char* data, unsigned length)
282 if (m_webMediaPlayer.get())
283 return m_webMediaPlayer->sourceAppend(data, length);
287 void WebMediaPlayerClientImpl::sourceEndOfStream(WebCore::MediaPlayer::EndOfStreamStatus status)
289 if (m_webMediaPlayer.get())
290 m_webMediaPlayer->sourceEndOfStream(static_cast<WebMediaPlayer::EndOfStreamStatus>(status));
294 void WebMediaPlayerClientImpl::prepareToPlay()
300 IntSize WebMediaPlayerClientImpl::naturalSize() const
302 if (m_webMediaPlayer.get())
303 return m_webMediaPlayer->naturalSize();
307 bool WebMediaPlayerClientImpl::hasVideo() const
309 if (m_webMediaPlayer.get())
310 return m_webMediaPlayer->hasVideo();
314 bool WebMediaPlayerClientImpl::hasAudio() const
316 if (m_webMediaPlayer.get())
317 return m_webMediaPlayer->hasAudio();
321 void WebMediaPlayerClientImpl::setVisible(bool visible)
323 if (m_webMediaPlayer.get())
324 m_webMediaPlayer->setVisible(visible);
327 float WebMediaPlayerClientImpl::duration() const
329 if (m_webMediaPlayer.get())
330 return m_webMediaPlayer->duration();
334 float WebMediaPlayerClientImpl::currentTime() const
336 if (m_webMediaPlayer.get())
337 return m_webMediaPlayer->currentTime();
341 void WebMediaPlayerClientImpl::seek(float time)
343 if (m_webMediaPlayer.get())
344 m_webMediaPlayer->seek(time);
347 bool WebMediaPlayerClientImpl::seeking() const
349 if (m_webMediaPlayer.get())
350 return m_webMediaPlayer->seeking();
354 void WebMediaPlayerClientImpl::setEndTime(float time)
356 if (m_webMediaPlayer.get())
357 m_webMediaPlayer->setEndTime(time);
360 void WebMediaPlayerClientImpl::setRate(float rate)
362 if (m_webMediaPlayer.get())
363 m_webMediaPlayer->setRate(rate);
366 bool WebMediaPlayerClientImpl::paused() const
368 if (m_webMediaPlayer.get())
369 return m_webMediaPlayer->paused();
373 bool WebMediaPlayerClientImpl::supportsFullscreen() const
375 if (m_webMediaPlayer.get())
376 return m_webMediaPlayer->supportsFullscreen();
380 bool WebMediaPlayerClientImpl::supportsSave() const
382 if (m_webMediaPlayer.get())
383 return m_webMediaPlayer->supportsSave();
387 void WebMediaPlayerClientImpl::setVolume(float volume)
389 if (m_webMediaPlayer.get())
390 m_webMediaPlayer->setVolume(volume);
393 MediaPlayer::NetworkState WebMediaPlayerClientImpl::networkState() const
395 if (m_webMediaPlayer.get())
396 return static_cast<MediaPlayer::NetworkState>(m_webMediaPlayer->networkState());
397 return MediaPlayer::Empty;
400 MediaPlayer::ReadyState WebMediaPlayerClientImpl::readyState() const
402 if (m_webMediaPlayer.get())
403 return static_cast<MediaPlayer::ReadyState>(m_webMediaPlayer->readyState());
404 return MediaPlayer::HaveNothing;
407 float WebMediaPlayerClientImpl::maxTimeSeekable() const
409 if (m_webMediaPlayer.get())
410 return m_webMediaPlayer->maxTimeSeekable();
414 PassRefPtr<TimeRanges> WebMediaPlayerClientImpl::buffered() const
416 if (m_webMediaPlayer.get()) {
417 const WebTimeRanges& webRanges = m_webMediaPlayer->buffered();
419 // FIXME: Save the time ranges in a member variable and update it when needed.
420 RefPtr<TimeRanges> ranges = TimeRanges::create();
421 for (size_t i = 0; i < webRanges.size(); ++i)
422 ranges->add(webRanges[i].start, webRanges[i].end);
423 return ranges.release();
425 return TimeRanges::create();
428 int WebMediaPlayerClientImpl::dataRate() const
430 if (m_webMediaPlayer.get())
431 return m_webMediaPlayer->dataRate();
435 bool WebMediaPlayerClientImpl::totalBytesKnown() const
437 if (m_webMediaPlayer.get())
438 return m_webMediaPlayer->totalBytesKnown();
442 unsigned WebMediaPlayerClientImpl::totalBytes() const
444 if (m_webMediaPlayer.get())
445 return static_cast<unsigned>(m_webMediaPlayer->totalBytes());
449 unsigned WebMediaPlayerClientImpl::bytesLoaded() const
451 if (m_webMediaPlayer.get())
452 return static_cast<unsigned>(m_webMediaPlayer->bytesLoaded());
456 void WebMediaPlayerClientImpl::setSize(const IntSize& size)
458 if (m_webMediaPlayer.get())
459 m_webMediaPlayer->setSize(WebSize(size.width(), size.height()));
462 void WebMediaPlayerClientImpl::paint(GraphicsContext* context, const IntRect& rect)
464 #if USE(ACCELERATED_COMPOSITING)
465 // If we are using GPU to render video, ignore requests to paint frames into
466 // canvas because it will be taken care of by VideoLayerChromium.
467 if (acceleratedRenderingInUse())
470 paintCurrentFrameInContext(context, rect);
473 void WebMediaPlayerClientImpl::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& rect)
475 // Normally GraphicsContext operations do nothing when painting is disabled.
476 // Since we're accessing platformContext() directly we have to manually
478 if (m_webMediaPlayer.get() && !context->paintingDisabled()) {
479 #if WEBKIT_USING_SKIA
480 PlatformGraphicsContext* platformContext = context->platformContext();
481 WebCanvas* canvas = platformContext->canvas();
483 canvas->saveLayerAlpha(0, platformContext->getNormalizedAlpha());
485 m_webMediaPlayer->paint(canvas, rect);
488 #elif WEBKIT_USING_CG
489 m_webMediaPlayer->paint(context->platformContext(), rect);
496 void WebMediaPlayerClientImpl::setPreload(MediaPlayer::Preload preload)
500 if (m_webMediaPlayer.get())
501 m_webMediaPlayer->setPreload(static_cast<WebMediaPlayer::Preload>(preload));
503 if (m_delayingLoad && m_preload != MediaPlayer::None)
507 bool WebMediaPlayerClientImpl::hasSingleSecurityOrigin() const
509 if (m_webMediaPlayer.get())
510 return m_webMediaPlayer->hasSingleSecurityOrigin();
514 MediaPlayer::MovieLoadType WebMediaPlayerClientImpl::movieLoadType() const
516 if (m_webMediaPlayer.get())
517 return static_cast<MediaPlayer::MovieLoadType>(
518 m_webMediaPlayer->movieLoadType());
519 return MediaPlayer::Unknown;
522 float WebMediaPlayerClientImpl::mediaTimeForTimeValue(float timeValue) const
524 if (m_webMediaPlayer.get())
525 return m_webMediaPlayer->mediaTimeForTimeValue(timeValue);
529 unsigned WebMediaPlayerClientImpl::decodedFrameCount() const
531 if (m_webMediaPlayer.get())
532 return m_webMediaPlayer->decodedFrameCount();
536 unsigned WebMediaPlayerClientImpl::droppedFrameCount() const
538 if (m_webMediaPlayer.get())
539 return m_webMediaPlayer->droppedFrameCount();
543 unsigned WebMediaPlayerClientImpl::audioDecodedByteCount() const
545 if (m_webMediaPlayer.get())
546 return m_webMediaPlayer->audioDecodedByteCount();
550 unsigned WebMediaPlayerClientImpl::videoDecodedByteCount() const
552 if (m_webMediaPlayer.get())
553 return m_webMediaPlayer->videoDecodedByteCount();
557 WebCore::AudioSourceProvider* WebMediaPlayerClientImpl::audioSourceProvider()
559 #if ENABLE(WEB_AUDIO)
560 if (m_webMediaPlayer.get()) {
561 // Wrap the WebAudioSourceProvider in the form of WebCore::AudioSourceProvider.
562 m_audioSourceProvider.initialize(m_webMediaPlayer->audioSourceProvider());
563 return &m_audioSourceProvider;
569 #if USE(ACCELERATED_COMPOSITING)
570 bool WebMediaPlayerClientImpl::supportsAcceleratedRendering() const
572 return m_supportsAcceleratedCompositing;
575 bool WebMediaPlayerClientImpl::acceleratedRenderingInUse()
577 return m_videoLayer.get() && m_videoLayer->layerTreeHost();
580 VideoFrameChromium* WebMediaPlayerClientImpl::getCurrentFrame()
582 VideoFrameChromium* videoFrame = 0;
583 if (m_webMediaPlayer.get()) {
584 WebVideoFrame* webkitVideoFrame = m_webMediaPlayer->getCurrentFrame();
585 if (webkitVideoFrame)
586 videoFrame = new VideoFrameChromiumImpl(webkitVideoFrame);
591 void WebMediaPlayerClientImpl::putCurrentFrame(VideoFrameChromium* videoFrame)
594 if (m_webMediaPlayer.get()) {
595 m_webMediaPlayer->putCurrentFrame(
596 VideoFrameChromiumImpl::toWebVideoFrame(videoFrame));
603 PassOwnPtr<MediaPlayerPrivateInterface> WebMediaPlayerClientImpl::create(MediaPlayer* player)
605 OwnPtr<WebMediaPlayerClientImpl> client = adoptPtr(new WebMediaPlayerClientImpl());
606 client->m_mediaPlayer = player;
608 #if USE(ACCELERATED_COMPOSITING)
609 Frame* frame = static_cast<HTMLMediaElement*>(
610 client->m_mediaPlayer->mediaPlayerClient())->document()->frame();
612 // This does not actually check whether the hardware can support accelerated
613 // compositing, but only if the flag is set. However, this is checked lazily
614 // in WebViewImpl::setIsAcceleratedCompositingActive() and will fail there
616 client->m_supportsAcceleratedCompositing =
617 frame->contentRenderer()->compositor()->hasAcceleratedCompositing();
620 return client.release();
623 void WebMediaPlayerClientImpl::getSupportedTypes(HashSet<String>& supportedTypes)
625 // FIXME: integrate this list with WebMediaPlayerClientImpl::supportsType.
629 MediaPlayer::SupportsType WebMediaPlayerClientImpl::supportsType(const String& type,
630 const String& codecs)
632 WebMimeRegistry::SupportsType supportsType = webKitPlatformSupport()->mimeRegistry()->supportsMediaMIMEType(type, codecs);
634 switch (supportsType) {
636 ASSERT_NOT_REACHED();
637 case WebMimeRegistry::IsNotSupported:
638 return MediaPlayer::IsNotSupported;
639 case WebMimeRegistry::IsSupported:
640 return MediaPlayer::IsSupported;
641 case WebMimeRegistry::MayBeSupported:
642 return MediaPlayer::MayBeSupported;
644 return MediaPlayer::IsNotSupported;
647 void WebMediaPlayerClientImpl::startDelayedLoad()
649 ASSERT(m_delayingLoad);
650 ASSERT(!m_webMediaPlayer.get());
652 m_delayingLoad = false;
657 WebMediaPlayerClientImpl::WebMediaPlayerClientImpl()
659 , m_delayingLoad(false)
660 , m_preload(MediaPlayer::MetaData)
661 #if USE(ACCELERATED_COMPOSITING)
663 , m_supportsAcceleratedCompositing(false)
668 #if ENABLE(WEB_AUDIO)
669 void WebMediaPlayerClientImpl::AudioSourceProviderImpl::provideInput(WebCore::AudioBus* bus, size_t framesToProcess)
675 ASSERT(m_webAudioSourceProvider);
676 if (!m_webAudioSourceProvider) {
681 // Wrap the AudioBus channel data using WebVector.
682 size_t n = bus->numberOfChannels();
683 WebVector<float*> webAudioData(n);
684 for (size_t i = 0; i < n; ++i)
685 webAudioData[i] = bus->channel(i)->data();
687 m_webAudioSourceProvider->provideInput(webAudioData, framesToProcess);
691 } // namespace WebKit
693 #endif // ENABLE(VIDEO)