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 #if ENABLE(VIDEO)
9
10 #include "Frame.h"
11 #include "GraphicsContext.h"
12 #include "HTMLMediaElement.h"
13 #include "IntSize.h"
14 #include "KURL.h"
15 #include "MediaPlayer.h"
16 #include "NotImplemented.h"
17 #include "RenderView.h"
18 #include "TimeRanges.h"
19 #include "VideoLayerChromium.h"
20
21 #if USE(ACCELERATED_COMPOSITING)
22 #include "RenderLayerCompositor.h"
23 #endif
24
25 #include "VideoFrameChromium.h"
26 #include "VideoFrameChromiumImpl.h"
27 #include "WebCanvas.h"
28 #include "WebCString.h"
29 #include "WebFrameClient.h"
30 #include "WebFrameImpl.h"
31 #include "WebKit.h"
32 #include "WebKitClient.h"
33 #include "WebMediaElement.h"
34 #include "WebMediaPlayer.h"
35 #include "WebMimeRegistry.h"
36 #include "WebRect.h"
37 #include "WebSize.h"
38 #include "WebString.h"
39 #include "WebURL.h"
40 #include "WebViewImpl.h"
41
42 // WebCommon.h defines WEBKIT_USING_SKIA so this has to be included last.
43 #if WEBKIT_USING_SKIA
44 #include "PlatformContextSkia.h"
45 #endif
46
47 #include <wtf/Assertions.h>
48 #include <wtf/text/CString.h>
49
50 using namespace WebCore;
51
52 namespace WebKit {
53
createWebMediaPlayer(WebMediaPlayerClient * client,Frame * frame)54 static WebMediaPlayer* createWebMediaPlayer(
55 WebMediaPlayerClient* client, Frame* frame)
56 {
57 WebFrameImpl* webFrame = WebFrameImpl::fromFrame(frame);
58
59 if (!webFrame->client())
60 return 0;
61 return webFrame->client()->createMediaPlayer(webFrame, client);
62 }
63
64 bool WebMediaPlayerClientImpl::m_isEnabled = false;
65
isEnabled()66 bool WebMediaPlayerClientImpl::isEnabled()
67 {
68 return m_isEnabled;
69 }
70
setIsEnabled(bool isEnabled)71 void WebMediaPlayerClientImpl::setIsEnabled(bool isEnabled)
72 {
73 m_isEnabled = isEnabled;
74 }
75
registerSelf(MediaEngineRegistrar registrar)76 void WebMediaPlayerClientImpl::registerSelf(MediaEngineRegistrar registrar)
77 {
78 if (m_isEnabled) {
79 registrar(WebMediaPlayerClientImpl::create,
80 WebMediaPlayerClientImpl::getSupportedTypes,
81 WebMediaPlayerClientImpl::supportsType,
82 0,
83 0,
84 0);
85 }
86 }
87
fromMediaElement(const WebMediaElement * element)88 WebMediaPlayerClientImpl* WebMediaPlayerClientImpl::fromMediaElement(const WebMediaElement* element)
89 {
90 PlatformMedia pm = element->constUnwrap<HTMLMediaElement>()->platformMedia();
91 return static_cast<WebMediaPlayerClientImpl*>(pm.media.chromiumMediaPlayer);
92 }
93
mediaPlayer() const94 WebMediaPlayer* WebMediaPlayerClientImpl::mediaPlayer() const
95 {
96 return m_webMediaPlayer.get();
97 }
98
99 // WebMediaPlayerClient --------------------------------------------------------
100
~WebMediaPlayerClientImpl()101 WebMediaPlayerClientImpl::~WebMediaPlayerClientImpl()
102 {
103 // VideoLayerChromium may outlive this object so make sure all frames are
104 // released.
105 #if USE(ACCELERATED_COMPOSITING)
106 if (m_videoLayer.get())
107 m_videoLayer->releaseCurrentFrame();
108 #endif
109 }
110
networkStateChanged()111 void WebMediaPlayerClientImpl::networkStateChanged()
112 {
113 ASSERT(m_mediaPlayer);
114 m_mediaPlayer->networkStateChanged();
115 }
116
readyStateChanged()117 void WebMediaPlayerClientImpl::readyStateChanged()
118 {
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);
124 #endif
125 }
126
volumeChanged(float newVolume)127 void WebMediaPlayerClientImpl::volumeChanged(float newVolume)
128 {
129 ASSERT(m_mediaPlayer);
130 m_mediaPlayer->volumeChanged(newVolume);
131 }
132
muteChanged(bool newMute)133 void WebMediaPlayerClientImpl::muteChanged(bool newMute)
134 {
135 ASSERT(m_mediaPlayer);
136 m_mediaPlayer->muteChanged(newMute);
137 }
138
timeChanged()139 void WebMediaPlayerClientImpl::timeChanged()
140 {
141 ASSERT(m_mediaPlayer);
142 m_mediaPlayer->timeChanged();
143 }
144
repaint()145 void WebMediaPlayerClientImpl::repaint()
146 {
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()));
151 #endif
152 m_mediaPlayer->repaint();
153 }
154
durationChanged()155 void WebMediaPlayerClientImpl::durationChanged()
156 {
157 ASSERT(m_mediaPlayer);
158 m_mediaPlayer->durationChanged();
159 }
160
rateChanged()161 void WebMediaPlayerClientImpl::rateChanged()
162 {
163 ASSERT(m_mediaPlayer);
164 m_mediaPlayer->rateChanged();
165 }
166
sizeChanged()167 void WebMediaPlayerClientImpl::sizeChanged()
168 {
169 ASSERT(m_mediaPlayer);
170 m_mediaPlayer->sizeChanged();
171 }
172
sawUnsupportedTracks()173 void WebMediaPlayerClientImpl::sawUnsupportedTracks()
174 {
175 ASSERT(m_mediaPlayer);
176 m_mediaPlayer->mediaPlayerClient()->mediaPlayerSawUnsupportedTracks(m_mediaPlayer);
177 }
178
volume() const179 float WebMediaPlayerClientImpl::volume() const
180 {
181 if (m_mediaPlayer)
182 return m_mediaPlayer->volume();
183 return 0.0f;
184 }
185
playbackStateChanged()186 void WebMediaPlayerClientImpl::playbackStateChanged()
187 {
188 ASSERT(m_mediaPlayer);
189 m_mediaPlayer->playbackStateChanged();
190 }
191
preload() const192 WebMediaPlayer::Preload WebMediaPlayerClientImpl::preload() const
193 {
194 if (m_mediaPlayer)
195 return static_cast<WebMediaPlayer::Preload>(m_mediaPlayer->preload());
196 return static_cast<WebMediaPlayer::Preload>(m_preload);
197 }
198
199 // MediaPlayerPrivateInterface -------------------------------------------------
200
load(const String & url)201 void WebMediaPlayerClientImpl::load(const String& url)
202 {
203 m_url = url;
204
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();
210 #endif
211
212 if (m_preload == MediaPlayer::None) {
213 m_webMediaPlayer.clear();
214 m_delayingLoad = true;
215 } else
216 loadInternal();
217 }
218
loadInternal()219 void WebMediaPlayerClientImpl::loadInternal()
220 {
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));
225 }
226
cancelLoad()227 void WebMediaPlayerClientImpl::cancelLoad()
228 {
229 if (m_webMediaPlayer.get())
230 m_webMediaPlayer->cancelLoad();
231 }
232
233 #if USE(ACCELERATED_COMPOSITING)
platformLayer() const234 PlatformLayer* WebMediaPlayerClientImpl::platformLayer() const
235 {
236 ASSERT(m_supportsAcceleratedCompositing);
237 return m_videoLayer.get();
238 }
239 #endif
240
platformMedia() const241 PlatformMedia WebMediaPlayerClientImpl::platformMedia() const
242 {
243 PlatformMedia pm;
244 pm.type = PlatformMedia::ChromiumMediaPlayerType;
245 pm.media.chromiumMediaPlayer = const_cast<WebMediaPlayerClientImpl*>(this);
246 return pm;
247 }
248
play()249 void WebMediaPlayerClientImpl::play()
250 {
251 if (m_webMediaPlayer.get())
252 m_webMediaPlayer->play();
253 }
254
pause()255 void WebMediaPlayerClientImpl::pause()
256 {
257 if (m_webMediaPlayer.get())
258 m_webMediaPlayer->pause();
259 }
260
prepareToPlay()261 void WebMediaPlayerClientImpl::prepareToPlay()
262 {
263 if (m_delayingLoad)
264 startDelayedLoad();
265 }
266
naturalSize() const267 IntSize WebMediaPlayerClientImpl::naturalSize() const
268 {
269 if (m_webMediaPlayer.get())
270 return m_webMediaPlayer->naturalSize();
271 return IntSize();
272 }
273
hasVideo() const274 bool WebMediaPlayerClientImpl::hasVideo() const
275 {
276 if (m_webMediaPlayer.get())
277 return m_webMediaPlayer->hasVideo();
278 return false;
279 }
280
hasAudio() const281 bool WebMediaPlayerClientImpl::hasAudio() const
282 {
283 if (m_webMediaPlayer.get())
284 return m_webMediaPlayer->hasAudio();
285 return false;
286 }
287
setVisible(bool visible)288 void WebMediaPlayerClientImpl::setVisible(bool visible)
289 {
290 if (m_webMediaPlayer.get())
291 m_webMediaPlayer->setVisible(visible);
292 }
293
duration() const294 float WebMediaPlayerClientImpl::duration() const
295 {
296 if (m_webMediaPlayer.get())
297 return m_webMediaPlayer->duration();
298 return 0.0f;
299 }
300
currentTime() const301 float WebMediaPlayerClientImpl::currentTime() const
302 {
303 if (m_webMediaPlayer.get())
304 return m_webMediaPlayer->currentTime();
305 return 0.0f;
306 }
307
seek(float time)308 void WebMediaPlayerClientImpl::seek(float time)
309 {
310 if (m_webMediaPlayer.get())
311 m_webMediaPlayer->seek(time);
312 }
313
seeking() const314 bool WebMediaPlayerClientImpl::seeking() const
315 {
316 if (m_webMediaPlayer.get())
317 return m_webMediaPlayer->seeking();
318 return false;
319 }
320
setEndTime(float time)321 void WebMediaPlayerClientImpl::setEndTime(float time)
322 {
323 if (m_webMediaPlayer.get())
324 m_webMediaPlayer->setEndTime(time);
325 }
326
setRate(float rate)327 void WebMediaPlayerClientImpl::setRate(float rate)
328 {
329 if (m_webMediaPlayer.get())
330 m_webMediaPlayer->setRate(rate);
331 }
332
paused() const333 bool WebMediaPlayerClientImpl::paused() const
334 {
335 if (m_webMediaPlayer.get())
336 return m_webMediaPlayer->paused();
337 return false;
338 }
339
supportsFullscreen() const340 bool WebMediaPlayerClientImpl::supportsFullscreen() const
341 {
342 if (m_webMediaPlayer.get())
343 return m_webMediaPlayer->supportsFullscreen();
344 return false;
345 }
346
supportsSave() const347 bool WebMediaPlayerClientImpl::supportsSave() const
348 {
349 if (m_webMediaPlayer.get())
350 return m_webMediaPlayer->supportsSave();
351 return false;
352 }
353
setVolume(float volume)354 void WebMediaPlayerClientImpl::setVolume(float volume)
355 {
356 if (m_webMediaPlayer.get())
357 m_webMediaPlayer->setVolume(volume);
358 }
359
networkState() const360 MediaPlayer::NetworkState WebMediaPlayerClientImpl::networkState() const
361 {
362 if (m_webMediaPlayer.get())
363 return static_cast<MediaPlayer::NetworkState>(m_webMediaPlayer->networkState());
364 return MediaPlayer::Empty;
365 }
366
readyState() const367 MediaPlayer::ReadyState WebMediaPlayerClientImpl::readyState() const
368 {
369 if (m_webMediaPlayer.get())
370 return static_cast<MediaPlayer::ReadyState>(m_webMediaPlayer->readyState());
371 return MediaPlayer::HaveNothing;
372 }
373
maxTimeSeekable() const374 float WebMediaPlayerClientImpl::maxTimeSeekable() const
375 {
376 if (m_webMediaPlayer.get())
377 return m_webMediaPlayer->maxTimeSeekable();
378 return 0.0f;
379 }
380
buffered() const381 PassRefPtr<TimeRanges> WebMediaPlayerClientImpl::buffered() const
382 {
383 if (m_webMediaPlayer.get()) {
384 const WebTimeRanges& webRanges = m_webMediaPlayer->buffered();
385
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();
391 }
392 return TimeRanges::create();
393 }
394
dataRate() const395 int WebMediaPlayerClientImpl::dataRate() const
396 {
397 if (m_webMediaPlayer.get())
398 return m_webMediaPlayer->dataRate();
399 return 0;
400 }
401
totalBytesKnown() const402 bool WebMediaPlayerClientImpl::totalBytesKnown() const
403 {
404 if (m_webMediaPlayer.get())
405 return m_webMediaPlayer->totalBytesKnown();
406 return false;
407 }
408
totalBytes() const409 unsigned WebMediaPlayerClientImpl::totalBytes() const
410 {
411 if (m_webMediaPlayer.get())
412 return static_cast<unsigned>(m_webMediaPlayer->totalBytes());
413 return 0;
414 }
415
bytesLoaded() const416 unsigned WebMediaPlayerClientImpl::bytesLoaded() const
417 {
418 if (m_webMediaPlayer.get())
419 return static_cast<unsigned>(m_webMediaPlayer->bytesLoaded());
420 return 0;
421 }
422
setSize(const IntSize & size)423 void WebMediaPlayerClientImpl::setSize(const IntSize& size)
424 {
425 if (m_webMediaPlayer.get())
426 m_webMediaPlayer->setSize(WebSize(size.width(), size.height()));
427 }
428
paint(GraphicsContext * context,const IntRect & rect)429 void WebMediaPlayerClientImpl::paint(GraphicsContext* context, const IntRect& rect)
430 {
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())
435 return;
436 #endif
437 paintCurrentFrameInContext(context, rect);
438 }
439
paintCurrentFrameInContext(GraphicsContext * context,const IntRect & rect)440 void WebMediaPlayerClientImpl::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& rect)
441 {
442 // Normally GraphicsContext operations do nothing when painting is disabled.
443 // Since we're accessing platformContext() directly we have to manually
444 // check.
445 if (m_webMediaPlayer.get() && !context->paintingDisabled()) {
446 #if WEBKIT_USING_SKIA
447 PlatformGraphicsContext* platformContext = context->platformContext();
448 WebCanvas* canvas = platformContext->canvas();
449
450 canvas->saveLayerAlpha(0, platformContext->getNormalizedAlpha());
451
452 m_webMediaPlayer->paint(canvas, rect);
453
454 canvas->restore();
455 #elif WEBKIT_USING_CG
456 m_webMediaPlayer->paint(context->platformContext(), rect);
457 #else
458 notImplemented();
459 #endif
460 }
461 }
462
setPreload(MediaPlayer::Preload preload)463 void WebMediaPlayerClientImpl::setPreload(MediaPlayer::Preload preload)
464 {
465 m_preload = preload;
466
467 if (m_webMediaPlayer.get())
468 m_webMediaPlayer->setPreload(static_cast<WebMediaPlayer::Preload>(preload));
469
470 if (m_delayingLoad && m_preload != MediaPlayer::None)
471 startDelayedLoad();
472 }
473
hasSingleSecurityOrigin() const474 bool WebMediaPlayerClientImpl::hasSingleSecurityOrigin() const
475 {
476 if (m_webMediaPlayer.get())
477 return m_webMediaPlayer->hasSingleSecurityOrigin();
478 return false;
479 }
480
movieLoadType() const481 MediaPlayer::MovieLoadType WebMediaPlayerClientImpl::movieLoadType() const
482 {
483 if (m_webMediaPlayer.get())
484 return static_cast<MediaPlayer::MovieLoadType>(
485 m_webMediaPlayer->movieLoadType());
486 return MediaPlayer::Unknown;
487 }
488
decodedFrameCount() const489 unsigned WebMediaPlayerClientImpl::decodedFrameCount() const
490 {
491 if (m_webMediaPlayer.get())
492 return m_webMediaPlayer->decodedFrameCount();
493 return 0;
494 }
495
droppedFrameCount() const496 unsigned WebMediaPlayerClientImpl::droppedFrameCount() const
497 {
498 if (m_webMediaPlayer.get())
499 return m_webMediaPlayer->droppedFrameCount();
500 return 0;
501 }
502
audioDecodedByteCount() const503 unsigned WebMediaPlayerClientImpl::audioDecodedByteCount() const
504 {
505 if (m_webMediaPlayer.get())
506 return m_webMediaPlayer->audioDecodedByteCount();
507 return 0;
508 }
509
videoDecodedByteCount() const510 unsigned WebMediaPlayerClientImpl::videoDecodedByteCount() const
511 {
512 if (m_webMediaPlayer.get())
513 return m_webMediaPlayer->videoDecodedByteCount();
514 return 0;
515 }
516
517 #if USE(ACCELERATED_COMPOSITING)
supportsAcceleratedRendering() const518 bool WebMediaPlayerClientImpl::supportsAcceleratedRendering() const
519 {
520 return m_supportsAcceleratedCompositing;
521 }
522
acceleratedRenderingInUse()523 bool WebMediaPlayerClientImpl::acceleratedRenderingInUse()
524 {
525 return m_videoLayer.get() && m_videoLayer->layerRenderer();
526 }
527
getCurrentFrame()528 VideoFrameChromium* WebMediaPlayerClientImpl::getCurrentFrame()
529 {
530 VideoFrameChromium* videoFrame = 0;
531 if (m_webMediaPlayer.get()) {
532 WebVideoFrame* webkitVideoFrame = m_webMediaPlayer->getCurrentFrame();
533 if (webkitVideoFrame)
534 videoFrame = new VideoFrameChromiumImpl(webkitVideoFrame);
535 }
536 return videoFrame;
537 }
538
putCurrentFrame(VideoFrameChromium * videoFrame)539 void WebMediaPlayerClientImpl::putCurrentFrame(VideoFrameChromium* videoFrame)
540 {
541 if (videoFrame) {
542 if (m_webMediaPlayer.get()) {
543 m_webMediaPlayer->putCurrentFrame(
544 VideoFrameChromiumImpl::toWebVideoFrame(videoFrame));
545 }
546 delete videoFrame;
547 }
548 }
549 #endif
550
create(MediaPlayer * player)551 MediaPlayerPrivateInterface* WebMediaPlayerClientImpl::create(MediaPlayer* player)
552 {
553 WebMediaPlayerClientImpl* client = new WebMediaPlayerClientImpl();
554 client->m_mediaPlayer = player;
555
556 #if USE(ACCELERATED_COMPOSITING)
557 Frame* frame = static_cast<HTMLMediaElement*>(
558 client->m_mediaPlayer->mediaPlayerClient())->document()->frame();
559
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
563 // if necessary.
564 client->m_supportsAcceleratedCompositing =
565 frame->contentRenderer()->compositor()->hasAcceleratedCompositing();
566 #endif
567
568 return client;
569 }
570
getSupportedTypes(HashSet<String> & supportedTypes)571 void WebMediaPlayerClientImpl::getSupportedTypes(HashSet<String>& supportedTypes)
572 {
573 // FIXME: integrate this list with WebMediaPlayerClientImpl::supportsType.
574 notImplemented();
575 }
576
supportsType(const String & type,const String & codecs)577 MediaPlayer::SupportsType WebMediaPlayerClientImpl::supportsType(const String& type,
578 const String& codecs)
579 {
580 WebMimeRegistry::SupportsType supportsType =
581 webKitClient()->mimeRegistry()->supportsMediaMIMEType(type, codecs);
582
583 switch (supportsType) {
584 default:
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;
592 }
593 return MediaPlayer::IsNotSupported;
594 }
595
startDelayedLoad()596 void WebMediaPlayerClientImpl::startDelayedLoad()
597 {
598 ASSERT(m_delayingLoad);
599 ASSERT(!m_webMediaPlayer.get());
600
601 m_delayingLoad = false;
602
603 loadInternal();
604 }
605
WebMediaPlayerClientImpl()606 WebMediaPlayerClientImpl::WebMediaPlayerClientImpl()
607 : m_mediaPlayer(0)
608 , m_delayingLoad(false)
609 , m_preload(MediaPlayer::MetaData)
610 #if USE(ACCELERATED_COMPOSITING)
611 , m_videoLayer(0)
612 , m_supportsAcceleratedCompositing(false)
613 #endif
614 {
615 }
616
617 } // namespace WebKit
618
619 #endif // ENABLE(VIDEO)
620