initial import
[vuplus_webkit] / Source / WebKit / chromium / src / 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 #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 "WebAudioSourceProvider.h"
28 #include "WebCanvas.h"
29 #include "WebCString.h"
30 #include "WebFrameClient.h"
31 #include "WebFrameImpl.h"
32 #include "WebKit.h"
33 #include "WebKitPlatformSupport.h"
34 #include "WebMediaElement.h"
35 #include "WebMediaPlayer.h"
36 #include "WebMimeRegistry.h"
37 #include "WebRect.h"
38 #include "WebSize.h"
39 #include "WebString.h"
40 #include "WebURL.h"
41 #include "WebViewImpl.h"
42
43 // WebCommon.h defines WEBKIT_USING_SKIA so this has to be included last.
44 #if WEBKIT_USING_SKIA
45 #include "PlatformContextSkia.h"
46 #endif
47
48 #include <wtf/Assertions.h>
49 #include <wtf/text/CString.h>
50
51 using namespace WebCore;
52
53 namespace WebKit {
54
55 static PassOwnPtr<WebMediaPlayer> createWebMediaPlayer(WebMediaPlayerClient* client, Frame* frame)
56 {
57     WebFrameImpl* webFrame = WebFrameImpl::fromFrame(frame);
58
59     if (!webFrame->client())
60         return nullptr;
61     return adoptPtr(webFrame->client()->createMediaPlayer(webFrame, client));
62 }
63
64 bool WebMediaPlayerClientImpl::m_isEnabled = false;
65
66 bool WebMediaPlayerClientImpl::isEnabled()
67 {
68     return m_isEnabled;
69 }
70
71 void WebMediaPlayerClientImpl::setIsEnabled(bool isEnabled)
72 {
73     m_isEnabled = isEnabled;
74 }
75
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
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
94 WebMediaPlayer* WebMediaPlayerClientImpl::mediaPlayer() const
95 {
96     return m_webMediaPlayer.get();
97 }
98
99 // WebMediaPlayerClient --------------------------------------------------------
100
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
111 void WebMediaPlayerClientImpl::networkStateChanged()
112 {
113     ASSERT(m_mediaPlayer);
114     m_mediaPlayer->networkStateChanged();
115 }
116
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
127 void WebMediaPlayerClientImpl::volumeChanged(float newVolume)
128 {
129     ASSERT(m_mediaPlayer);
130     m_mediaPlayer->volumeChanged(newVolume);
131 }
132
133 void WebMediaPlayerClientImpl::muteChanged(bool newMute)
134 {
135     ASSERT(m_mediaPlayer);
136     m_mediaPlayer->muteChanged(newMute);
137 }
138
139 void WebMediaPlayerClientImpl::timeChanged()
140 {
141     ASSERT(m_mediaPlayer);
142     m_mediaPlayer->timeChanged();
143 }
144
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
155 void WebMediaPlayerClientImpl::durationChanged()
156 {
157     ASSERT(m_mediaPlayer);
158     m_mediaPlayer->durationChanged();
159 }
160
161 void WebMediaPlayerClientImpl::rateChanged()
162 {
163     ASSERT(m_mediaPlayer);
164     m_mediaPlayer->rateChanged();
165 }
166
167 void WebMediaPlayerClientImpl::sizeChanged()
168 {
169     ASSERT(m_mediaPlayer);
170     m_mediaPlayer->sizeChanged();
171 }
172
173 void WebMediaPlayerClientImpl::sawUnsupportedTracks()
174 {
175     ASSERT(m_mediaPlayer);
176     m_mediaPlayer->mediaPlayerClient()->mediaPlayerSawUnsupportedTracks(m_mediaPlayer);
177 }
178
179 float WebMediaPlayerClientImpl::volume() const
180 {
181     if (m_mediaPlayer)
182         return m_mediaPlayer->volume();
183     return 0.0f;
184 }
185
186 void WebMediaPlayerClientImpl::playbackStateChanged()
187 {
188     ASSERT(m_mediaPlayer);
189     m_mediaPlayer->playbackStateChanged();
190 }
191
192 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 void WebMediaPlayerClientImpl::sourceOpened()
200 {
201 #if ENABLE(MEDIA_SOURCE)
202     ASSERT(m_mediaPlayer);
203     m_mediaPlayer->sourceOpened();
204 #endif
205 }
206
207 WebKit::WebURL WebMediaPlayerClientImpl::sourceURL() const
208 {
209 #if ENABLE(MEDIA_SOURCE)
210     ASSERT(m_mediaPlayer);
211     return KURL(ParsedURLString, m_mediaPlayer->sourceURL());
212 #else
213     return KURL();
214 #endif
215 }
216
217 // MediaPlayerPrivateInterface -------------------------------------------------
218
219 void WebMediaPlayerClientImpl::load(const String& url)
220 {
221     m_url = url;
222
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();
228 #endif
229
230     if (m_preload == MediaPlayer::None) {
231         m_webMediaPlayer.clear();
232         m_delayingLoad = true;
233     } else
234         loadInternal();
235 }
236
237 void WebMediaPlayerClientImpl::loadInternal()
238 {
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));
243 }
244
245 void WebMediaPlayerClientImpl::cancelLoad()
246 {
247     if (m_webMediaPlayer.get())
248         m_webMediaPlayer->cancelLoad();
249 }
250
251 #if USE(ACCELERATED_COMPOSITING)
252 PlatformLayer* WebMediaPlayerClientImpl::platformLayer() const
253 {
254     ASSERT(m_supportsAcceleratedCompositing);
255     return m_videoLayer.get();
256 }
257 #endif
258
259 PlatformMedia WebMediaPlayerClientImpl::platformMedia() const
260 {
261     PlatformMedia pm;
262     pm.type = PlatformMedia::ChromiumMediaPlayerType;
263     pm.media.chromiumMediaPlayer = const_cast<WebMediaPlayerClientImpl*>(this);
264     return pm;
265 }
266
267 void WebMediaPlayerClientImpl::play()
268 {
269     if (m_webMediaPlayer.get())
270         m_webMediaPlayer->play();
271 }
272
273 void WebMediaPlayerClientImpl::pause()
274 {
275     if (m_webMediaPlayer.get())
276         m_webMediaPlayer->pause();
277 }
278
279 #if ENABLE(MEDIA_SOURCE)
280 bool WebMediaPlayerClientImpl::sourceAppend(const unsigned char* data, unsigned length)
281 {
282     if (m_webMediaPlayer.get())
283         return m_webMediaPlayer->sourceAppend(data, length);
284     return false;
285 }
286
287 void WebMediaPlayerClientImpl::sourceEndOfStream(WebCore::MediaPlayer::EndOfStreamStatus status)
288 {
289     if (m_webMediaPlayer.get())
290         m_webMediaPlayer->sourceEndOfStream(static_cast<WebMediaPlayer::EndOfStreamStatus>(status));
291 }
292 #endif
293
294 void WebMediaPlayerClientImpl::prepareToPlay()
295 {
296     if (m_delayingLoad)
297         startDelayedLoad();
298 }
299
300 IntSize WebMediaPlayerClientImpl::naturalSize() const
301 {
302     if (m_webMediaPlayer.get())
303         return m_webMediaPlayer->naturalSize();
304     return IntSize();
305 }
306
307 bool WebMediaPlayerClientImpl::hasVideo() const
308 {
309     if (m_webMediaPlayer.get())
310         return m_webMediaPlayer->hasVideo();
311     return false;
312 }
313
314 bool WebMediaPlayerClientImpl::hasAudio() const
315 {
316     if (m_webMediaPlayer.get())
317         return m_webMediaPlayer->hasAudio();
318     return false;
319 }
320
321 void WebMediaPlayerClientImpl::setVisible(bool visible)
322 {
323     if (m_webMediaPlayer.get())
324         m_webMediaPlayer->setVisible(visible);
325 }
326
327 float WebMediaPlayerClientImpl::duration() const
328 {
329     if (m_webMediaPlayer.get())
330         return m_webMediaPlayer->duration();
331     return 0.0f;
332 }
333
334 float WebMediaPlayerClientImpl::currentTime() const
335 {
336     if (m_webMediaPlayer.get())
337         return m_webMediaPlayer->currentTime();
338     return 0.0f;
339 }
340
341 void WebMediaPlayerClientImpl::seek(float time)
342 {
343     if (m_webMediaPlayer.get())
344         m_webMediaPlayer->seek(time);
345 }
346
347 bool WebMediaPlayerClientImpl::seeking() const
348 {
349     if (m_webMediaPlayer.get())
350         return m_webMediaPlayer->seeking();
351     return false;
352 }
353
354 void WebMediaPlayerClientImpl::setEndTime(float time)
355 {
356     if (m_webMediaPlayer.get())
357         m_webMediaPlayer->setEndTime(time);
358 }
359
360 void WebMediaPlayerClientImpl::setRate(float rate)
361 {
362     if (m_webMediaPlayer.get())
363         m_webMediaPlayer->setRate(rate);
364 }
365
366 bool WebMediaPlayerClientImpl::paused() const
367 {
368     if (m_webMediaPlayer.get())
369         return m_webMediaPlayer->paused();
370     return false;
371 }
372
373 bool WebMediaPlayerClientImpl::supportsFullscreen() const
374 {
375     if (m_webMediaPlayer.get())
376         return m_webMediaPlayer->supportsFullscreen();
377     return false;
378 }
379
380 bool WebMediaPlayerClientImpl::supportsSave() const
381 {
382     if (m_webMediaPlayer.get())
383         return m_webMediaPlayer->supportsSave();
384     return false;
385 }
386
387 void WebMediaPlayerClientImpl::setVolume(float volume)
388 {
389     if (m_webMediaPlayer.get())
390         m_webMediaPlayer->setVolume(volume);
391 }
392
393 MediaPlayer::NetworkState WebMediaPlayerClientImpl::networkState() const
394 {
395     if (m_webMediaPlayer.get())
396         return static_cast<MediaPlayer::NetworkState>(m_webMediaPlayer->networkState());
397     return MediaPlayer::Empty;
398 }
399
400 MediaPlayer::ReadyState WebMediaPlayerClientImpl::readyState() const
401 {
402     if (m_webMediaPlayer.get())
403         return static_cast<MediaPlayer::ReadyState>(m_webMediaPlayer->readyState());
404     return MediaPlayer::HaveNothing;
405 }
406
407 float WebMediaPlayerClientImpl::maxTimeSeekable() const
408 {
409     if (m_webMediaPlayer.get())
410         return m_webMediaPlayer->maxTimeSeekable();
411     return 0.0f;
412 }
413
414 PassRefPtr<TimeRanges> WebMediaPlayerClientImpl::buffered() const
415 {
416     if (m_webMediaPlayer.get()) {
417         const WebTimeRanges& webRanges = m_webMediaPlayer->buffered();
418
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();
424     }
425     return TimeRanges::create();
426 }
427
428 int WebMediaPlayerClientImpl::dataRate() const
429 {
430     if (m_webMediaPlayer.get())
431         return m_webMediaPlayer->dataRate();
432     return 0;
433 }
434
435 bool WebMediaPlayerClientImpl::totalBytesKnown() const
436 {
437     if (m_webMediaPlayer.get())
438         return m_webMediaPlayer->totalBytesKnown();
439     return false;
440 }
441
442 unsigned WebMediaPlayerClientImpl::totalBytes() const
443 {
444     if (m_webMediaPlayer.get())
445         return static_cast<unsigned>(m_webMediaPlayer->totalBytes());
446     return 0;
447 }
448
449 unsigned WebMediaPlayerClientImpl::bytesLoaded() const
450 {
451     if (m_webMediaPlayer.get())
452         return static_cast<unsigned>(m_webMediaPlayer->bytesLoaded());
453     return 0;
454 }
455
456 void WebMediaPlayerClientImpl::setSize(const IntSize& size)
457 {
458     if (m_webMediaPlayer.get())
459         m_webMediaPlayer->setSize(WebSize(size.width(), size.height()));
460 }
461
462 void WebMediaPlayerClientImpl::paint(GraphicsContext* context, const IntRect& rect)
463 {
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())
468         return;
469 #endif
470     paintCurrentFrameInContext(context, rect);
471 }
472
473 void WebMediaPlayerClientImpl::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& rect)
474 {
475     // Normally GraphicsContext operations do nothing when painting is disabled.
476     // Since we're accessing platformContext() directly we have to manually
477     // check.
478     if (m_webMediaPlayer.get() && !context->paintingDisabled()) {
479 #if WEBKIT_USING_SKIA
480         PlatformGraphicsContext* platformContext = context->platformContext();
481         WebCanvas* canvas = platformContext->canvas();
482
483         canvas->saveLayerAlpha(0, platformContext->getNormalizedAlpha());
484
485         m_webMediaPlayer->paint(canvas, rect);
486
487         canvas->restore();
488 #elif WEBKIT_USING_CG
489         m_webMediaPlayer->paint(context->platformContext(), rect);
490 #else
491         notImplemented();
492 #endif
493     }
494 }
495
496 void WebMediaPlayerClientImpl::setPreload(MediaPlayer::Preload preload)
497 {
498     m_preload = preload;
499
500     if (m_webMediaPlayer.get())
501         m_webMediaPlayer->setPreload(static_cast<WebMediaPlayer::Preload>(preload));
502
503     if (m_delayingLoad && m_preload != MediaPlayer::None)
504         startDelayedLoad();
505 }
506
507 bool WebMediaPlayerClientImpl::hasSingleSecurityOrigin() const
508 {
509     if (m_webMediaPlayer.get())
510         return m_webMediaPlayer->hasSingleSecurityOrigin();
511     return false;
512 }
513
514 MediaPlayer::MovieLoadType WebMediaPlayerClientImpl::movieLoadType() const
515 {
516     if (m_webMediaPlayer.get())
517         return static_cast<MediaPlayer::MovieLoadType>(
518             m_webMediaPlayer->movieLoadType());
519     return MediaPlayer::Unknown;
520 }
521
522 float WebMediaPlayerClientImpl::mediaTimeForTimeValue(float timeValue) const
523 {
524     if (m_webMediaPlayer.get())
525         return m_webMediaPlayer->mediaTimeForTimeValue(timeValue);
526     return timeValue;
527 }
528
529 unsigned WebMediaPlayerClientImpl::decodedFrameCount() const
530 {
531     if (m_webMediaPlayer.get())
532         return m_webMediaPlayer->decodedFrameCount();
533     return 0;
534 }
535
536 unsigned WebMediaPlayerClientImpl::droppedFrameCount() const
537 {
538     if (m_webMediaPlayer.get())
539         return m_webMediaPlayer->droppedFrameCount();
540     return 0;
541 }
542
543 unsigned WebMediaPlayerClientImpl::audioDecodedByteCount() const
544 {
545     if (m_webMediaPlayer.get())
546         return m_webMediaPlayer->audioDecodedByteCount();
547     return 0;
548 }
549
550 unsigned WebMediaPlayerClientImpl::videoDecodedByteCount() const
551 {
552     if (m_webMediaPlayer.get())
553         return m_webMediaPlayer->videoDecodedByteCount();
554     return 0;
555 }
556
557 WebCore::AudioSourceProvider* WebMediaPlayerClientImpl::audioSourceProvider()
558 {
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;
564     }
565 #endif
566     return 0;
567 }
568
569 #if USE(ACCELERATED_COMPOSITING)
570 bool WebMediaPlayerClientImpl::supportsAcceleratedRendering() const
571 {
572     return m_supportsAcceleratedCompositing;
573 }
574
575 bool WebMediaPlayerClientImpl::acceleratedRenderingInUse()
576 {
577     return m_videoLayer.get() && m_videoLayer->layerTreeHost();
578 }
579
580 VideoFrameChromium* WebMediaPlayerClientImpl::getCurrentFrame()
581 {
582     VideoFrameChromium* videoFrame = 0;
583     if (m_webMediaPlayer.get()) {
584         WebVideoFrame* webkitVideoFrame = m_webMediaPlayer->getCurrentFrame();
585         if (webkitVideoFrame)
586             videoFrame = new VideoFrameChromiumImpl(webkitVideoFrame);
587     }
588     return videoFrame;
589 }
590
591 void WebMediaPlayerClientImpl::putCurrentFrame(VideoFrameChromium* videoFrame)
592 {
593     if (videoFrame) {
594         if (m_webMediaPlayer.get()) {
595             m_webMediaPlayer->putCurrentFrame(
596                 VideoFrameChromiumImpl::toWebVideoFrame(videoFrame));
597         }
598         delete videoFrame;
599     }
600 }
601 #endif
602
603 PassOwnPtr<MediaPlayerPrivateInterface> WebMediaPlayerClientImpl::create(MediaPlayer* player)
604 {
605     OwnPtr<WebMediaPlayerClientImpl> client = adoptPtr(new WebMediaPlayerClientImpl());
606     client->m_mediaPlayer = player;
607
608 #if USE(ACCELERATED_COMPOSITING)
609     Frame* frame = static_cast<HTMLMediaElement*>(
610         client->m_mediaPlayer->mediaPlayerClient())->document()->frame();
611
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
615     // if necessary.
616     client->m_supportsAcceleratedCompositing =
617         frame->contentRenderer()->compositor()->hasAcceleratedCompositing();
618 #endif
619
620     return client.release();
621 }
622
623 void WebMediaPlayerClientImpl::getSupportedTypes(HashSet<String>& supportedTypes)
624 {
625     // FIXME: integrate this list with WebMediaPlayerClientImpl::supportsType.
626     notImplemented();
627 }
628
629 MediaPlayer::SupportsType WebMediaPlayerClientImpl::supportsType(const String& type,
630                                                                  const String& codecs)
631 {
632     WebMimeRegistry::SupportsType supportsType = webKitPlatformSupport()->mimeRegistry()->supportsMediaMIMEType(type, codecs);
633
634     switch (supportsType) {
635     default:
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;
643     }
644     return MediaPlayer::IsNotSupported;
645 }
646
647 void WebMediaPlayerClientImpl::startDelayedLoad()
648 {
649     ASSERT(m_delayingLoad);
650     ASSERT(!m_webMediaPlayer.get());
651
652     m_delayingLoad = false;
653
654     loadInternal();
655 }
656
657 WebMediaPlayerClientImpl::WebMediaPlayerClientImpl()
658     : m_mediaPlayer(0)
659     , m_delayingLoad(false)
660     , m_preload(MediaPlayer::MetaData)
661 #if USE(ACCELERATED_COMPOSITING)
662     , m_videoLayer(0)
663     , m_supportsAcceleratedCompositing(false)
664 #endif
665 {
666 }
667
668 #if ENABLE(WEB_AUDIO)
669 void WebMediaPlayerClientImpl::AudioSourceProviderImpl::provideInput(WebCore::AudioBus* bus, size_t framesToProcess)
670 {
671     ASSERT(bus);
672     if (!bus)
673         return;
674
675     ASSERT(m_webAudioSourceProvider);
676     if (!m_webAudioSourceProvider) {
677         bus->zero();
678         return;
679     }
680
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();
686
687     m_webAudioSourceProvider->provideInput(webAudioData, framesToProcess);
688 }
689 #endif
690
691 } // namespace WebKit
692
693 #endif  // ENABLE(VIDEO)