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 "WebCanvas.h"
28 #include "WebCString.h"
29 #include "WebFrameClient.h"
30 #include "WebFrameImpl.h"
32 #include "WebKitClient.h"
33 #include "WebMediaElement.h"
34 #include "WebMediaPlayer.h"
35 #include "WebMimeRegistry.h"
38 #include "WebString.h"
40 #include "WebViewImpl.h"
42 // WebCommon.h defines WEBKIT_USING_SKIA so this has to be included last.
44 #include "PlatformContextSkia.h"
47 #include <wtf/Assertions.h>
48 #include <wtf/text/CString.h>
50 using namespace WebCore;
54 static WebMediaPlayer* createWebMediaPlayer(
55 WebMediaPlayerClient* client, Frame* frame)
57 WebFrameImpl* webFrame = WebFrameImpl::fromFrame(frame);
59 if (!webFrame->client())
61 return 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 // MediaPlayerPrivateInterface -------------------------------------------------
201 void WebMediaPlayerClientImpl::load(const String& url)
205 // Video frame object is owned by WebMediaPlayer. Before destroying
206 // WebMediaPlayer all frames need to be released.
207 #if USE(ACCELERATED_COMPOSITING)
208 if (m_videoLayer.get())
209 m_videoLayer->releaseCurrentFrame();
212 if (m_preload == MediaPlayer::None) {
213 m_webMediaPlayer.clear();
214 m_delayingLoad = true;
219 void WebMediaPlayerClientImpl::loadInternal()
221 Frame* frame = static_cast<HTMLMediaElement*>(m_mediaPlayer->mediaPlayerClient())->document()->frame();
222 m_webMediaPlayer.set(createWebMediaPlayer(this, frame));
223 if (m_webMediaPlayer.get())
224 m_webMediaPlayer->load(KURL(ParsedURLString, m_url));
227 void WebMediaPlayerClientImpl::cancelLoad()
229 if (m_webMediaPlayer.get())
230 m_webMediaPlayer->cancelLoad();
233 #if USE(ACCELERATED_COMPOSITING)
234 PlatformLayer* WebMediaPlayerClientImpl::platformLayer() const
236 ASSERT(m_supportsAcceleratedCompositing);
237 return m_videoLayer.get();
241 PlatformMedia WebMediaPlayerClientImpl::platformMedia() const
244 pm.type = PlatformMedia::ChromiumMediaPlayerType;
245 pm.media.chromiumMediaPlayer = const_cast<WebMediaPlayerClientImpl*>(this);
249 void WebMediaPlayerClientImpl::play()
251 if (m_webMediaPlayer.get())
252 m_webMediaPlayer->play();
255 void WebMediaPlayerClientImpl::pause()
257 if (m_webMediaPlayer.get())
258 m_webMediaPlayer->pause();
261 void WebMediaPlayerClientImpl::prepareToPlay()
267 IntSize WebMediaPlayerClientImpl::naturalSize() const
269 if (m_webMediaPlayer.get())
270 return m_webMediaPlayer->naturalSize();
274 bool WebMediaPlayerClientImpl::hasVideo() const
276 if (m_webMediaPlayer.get())
277 return m_webMediaPlayer->hasVideo();
281 bool WebMediaPlayerClientImpl::hasAudio() const
283 if (m_webMediaPlayer.get())
284 return m_webMediaPlayer->hasAudio();
288 void WebMediaPlayerClientImpl::setVisible(bool visible)
290 if (m_webMediaPlayer.get())
291 m_webMediaPlayer->setVisible(visible);
294 float WebMediaPlayerClientImpl::duration() const
296 if (m_webMediaPlayer.get())
297 return m_webMediaPlayer->duration();
301 float WebMediaPlayerClientImpl::currentTime() const
303 if (m_webMediaPlayer.get())
304 return m_webMediaPlayer->currentTime();
308 void WebMediaPlayerClientImpl::seek(float time)
310 if (m_webMediaPlayer.get())
311 m_webMediaPlayer->seek(time);
314 bool WebMediaPlayerClientImpl::seeking() const
316 if (m_webMediaPlayer.get())
317 return m_webMediaPlayer->seeking();
321 void WebMediaPlayerClientImpl::setEndTime(float time)
323 if (m_webMediaPlayer.get())
324 m_webMediaPlayer->setEndTime(time);
327 void WebMediaPlayerClientImpl::setRate(float rate)
329 if (m_webMediaPlayer.get())
330 m_webMediaPlayer->setRate(rate);
333 bool WebMediaPlayerClientImpl::paused() const
335 if (m_webMediaPlayer.get())
336 return m_webMediaPlayer->paused();
340 bool WebMediaPlayerClientImpl::supportsFullscreen() const
342 if (m_webMediaPlayer.get())
343 return m_webMediaPlayer->supportsFullscreen();
347 bool WebMediaPlayerClientImpl::supportsSave() const
349 if (m_webMediaPlayer.get())
350 return m_webMediaPlayer->supportsSave();
354 void WebMediaPlayerClientImpl::setVolume(float volume)
356 if (m_webMediaPlayer.get())
357 m_webMediaPlayer->setVolume(volume);
360 MediaPlayer::NetworkState WebMediaPlayerClientImpl::networkState() const
362 if (m_webMediaPlayer.get())
363 return static_cast<MediaPlayer::NetworkState>(m_webMediaPlayer->networkState());
364 return MediaPlayer::Empty;
367 MediaPlayer::ReadyState WebMediaPlayerClientImpl::readyState() const
369 if (m_webMediaPlayer.get())
370 return static_cast<MediaPlayer::ReadyState>(m_webMediaPlayer->readyState());
371 return MediaPlayer::HaveNothing;
374 float WebMediaPlayerClientImpl::maxTimeSeekable() const
376 if (m_webMediaPlayer.get())
377 return m_webMediaPlayer->maxTimeSeekable();
381 PassRefPtr<TimeRanges> WebMediaPlayerClientImpl::buffered() const
383 if (m_webMediaPlayer.get()) {
384 const WebTimeRanges& webRanges = m_webMediaPlayer->buffered();
386 // FIXME: Save the time ranges in a member variable and update it when needed.
387 RefPtr<TimeRanges> ranges = TimeRanges::create();
388 for (size_t i = 0; i < webRanges.size(); ++i)
389 ranges->add(webRanges[i].start, webRanges[i].end);
390 return ranges.release();
392 return TimeRanges::create();
395 int WebMediaPlayerClientImpl::dataRate() const
397 if (m_webMediaPlayer.get())
398 return m_webMediaPlayer->dataRate();
402 bool WebMediaPlayerClientImpl::totalBytesKnown() const
404 if (m_webMediaPlayer.get())
405 return m_webMediaPlayer->totalBytesKnown();
409 unsigned WebMediaPlayerClientImpl::totalBytes() const
411 if (m_webMediaPlayer.get())
412 return static_cast<unsigned>(m_webMediaPlayer->totalBytes());
416 unsigned WebMediaPlayerClientImpl::bytesLoaded() const
418 if (m_webMediaPlayer.get())
419 return static_cast<unsigned>(m_webMediaPlayer->bytesLoaded());
423 void WebMediaPlayerClientImpl::setSize(const IntSize& size)
425 if (m_webMediaPlayer.get())
426 m_webMediaPlayer->setSize(WebSize(size.width(), size.height()));
429 void WebMediaPlayerClientImpl::paint(GraphicsContext* context, const IntRect& rect)
431 #if USE(ACCELERATED_COMPOSITING)
432 // If we are using GPU to render video, ignore requests to paint frames into
433 // canvas because it will be taken care of by VideoLayerChromium.
434 if (acceleratedRenderingInUse())
437 paintCurrentFrameInContext(context, rect);
440 void WebMediaPlayerClientImpl::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& rect)
442 // Normally GraphicsContext operations do nothing when painting is disabled.
443 // Since we're accessing platformContext() directly we have to manually
445 if (m_webMediaPlayer.get() && !context->paintingDisabled()) {
446 #if WEBKIT_USING_SKIA
447 PlatformGraphicsContext* platformContext = context->platformContext();
448 WebCanvas* canvas = platformContext->canvas();
450 canvas->saveLayerAlpha(0, platformContext->getNormalizedAlpha());
452 m_webMediaPlayer->paint(canvas, rect);
455 #elif WEBKIT_USING_CG
456 m_webMediaPlayer->paint(context->platformContext(), rect);
463 void WebMediaPlayerClientImpl::setPreload(MediaPlayer::Preload preload)
467 if (m_webMediaPlayer.get())
468 m_webMediaPlayer->setPreload(static_cast<WebMediaPlayer::Preload>(preload));
470 if (m_delayingLoad && m_preload != MediaPlayer::None)
474 bool WebMediaPlayerClientImpl::hasSingleSecurityOrigin() const
476 if (m_webMediaPlayer.get())
477 return m_webMediaPlayer->hasSingleSecurityOrigin();
481 MediaPlayer::MovieLoadType WebMediaPlayerClientImpl::movieLoadType() const
483 if (m_webMediaPlayer.get())
484 return static_cast<MediaPlayer::MovieLoadType>(
485 m_webMediaPlayer->movieLoadType());
486 return MediaPlayer::Unknown;
489 unsigned WebMediaPlayerClientImpl::decodedFrameCount() const
491 if (m_webMediaPlayer.get())
492 return m_webMediaPlayer->decodedFrameCount();
496 unsigned WebMediaPlayerClientImpl::droppedFrameCount() const
498 if (m_webMediaPlayer.get())
499 return m_webMediaPlayer->droppedFrameCount();
503 unsigned WebMediaPlayerClientImpl::audioDecodedByteCount() const
505 if (m_webMediaPlayer.get())
506 return m_webMediaPlayer->audioDecodedByteCount();
510 unsigned WebMediaPlayerClientImpl::videoDecodedByteCount() const
512 if (m_webMediaPlayer.get())
513 return m_webMediaPlayer->videoDecodedByteCount();
517 #if USE(ACCELERATED_COMPOSITING)
518 bool WebMediaPlayerClientImpl::supportsAcceleratedRendering() const
520 return m_supportsAcceleratedCompositing;
523 bool WebMediaPlayerClientImpl::acceleratedRenderingInUse()
525 return m_videoLayer.get() && m_videoLayer->layerRenderer();
528 VideoFrameChromium* WebMediaPlayerClientImpl::getCurrentFrame()
530 VideoFrameChromium* videoFrame = 0;
531 if (m_webMediaPlayer.get()) {
532 WebVideoFrame* webkitVideoFrame = m_webMediaPlayer->getCurrentFrame();
533 if (webkitVideoFrame)
534 videoFrame = new VideoFrameChromiumImpl(webkitVideoFrame);
539 void WebMediaPlayerClientImpl::putCurrentFrame(VideoFrameChromium* videoFrame)
542 if (m_webMediaPlayer.get()) {
543 m_webMediaPlayer->putCurrentFrame(
544 VideoFrameChromiumImpl::toWebVideoFrame(videoFrame));
551 MediaPlayerPrivateInterface* WebMediaPlayerClientImpl::create(MediaPlayer* player)
553 WebMediaPlayerClientImpl* client = new WebMediaPlayerClientImpl();
554 client->m_mediaPlayer = player;
556 #if USE(ACCELERATED_COMPOSITING)
557 Frame* frame = static_cast<HTMLMediaElement*>(
558 client->m_mediaPlayer->mediaPlayerClient())->document()->frame();
560 // This does not actually check whether the hardware can support accelerated
561 // compositing, but only if the flag is set. However, this is checked lazily
562 // in WebViewImpl::setIsAcceleratedCompositingActive() and will fail there
564 client->m_supportsAcceleratedCompositing =
565 frame->contentRenderer()->compositor()->hasAcceleratedCompositing();
571 void WebMediaPlayerClientImpl::getSupportedTypes(HashSet<String>& supportedTypes)
573 // FIXME: integrate this list with WebMediaPlayerClientImpl::supportsType.
577 MediaPlayer::SupportsType WebMediaPlayerClientImpl::supportsType(const String& type,
578 const String& codecs)
580 WebMimeRegistry::SupportsType supportsType =
581 webKitClient()->mimeRegistry()->supportsMediaMIMEType(type, codecs);
583 switch (supportsType) {
585 ASSERT_NOT_REACHED();
586 case WebMimeRegistry::IsNotSupported:
587 return MediaPlayer::IsNotSupported;
588 case WebMimeRegistry::IsSupported:
589 return MediaPlayer::IsSupported;
590 case WebMimeRegistry::MayBeSupported:
591 return MediaPlayer::MayBeSupported;
593 return MediaPlayer::IsNotSupported;
596 void WebMediaPlayerClientImpl::startDelayedLoad()
598 ASSERT(m_delayingLoad);
599 ASSERT(!m_webMediaPlayer.get());
601 m_delayingLoad = false;
606 WebMediaPlayerClientImpl::WebMediaPlayerClientImpl()
608 , m_delayingLoad(false)
609 , m_preload(MediaPlayer::MetaData)
610 #if USE(ACCELERATED_COMPOSITING)
612 , m_supportsAcceleratedCompositing(false)
617 } // namespace WebKit
619 #endif // ENABLE(VIDEO)