2 * Copyright (C) 2011, 2012 Research In Motion Limited. All rights reserved.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "MediaPlayerPrivateBlackBerry.h"
24 #include "CookieManager.h"
25 #include "CredentialStorage.h"
26 #include "HostWindow.h"
27 #include "MediaStreamDescriptor.h"
28 #include "MediaStreamRegistry.h"
30 #include <BlackBerryPlatformDeviceInfo.h>
31 #include <BlackBerryPlatformPrimitives.h>
32 #include <BlackBerryPlatformSettings.h>
33 #include <FrameLoaderClientBlackBerry.h>
35 #if USE(ACCELERATED_COMPOSITING)
36 #include "VideoLayerWebKitThread.h"
37 #include <BlackBerryPlatformGLES2Program.h>
38 #include <GLES2/gl2.h>
41 #include <TiledImage.h>
44 using namespace BlackBerry::Platform;
48 // Static callback functions for factory
49 PassOwnPtr<MediaPlayerPrivateInterface> MediaPlayerPrivate::create(MediaPlayer* player)
51 return adoptPtr(new MediaPlayerPrivate(player));
54 void MediaPlayerPrivate::registerMediaEngine(MediaEngineRegistrar registrar)
56 registrar(create, getSupportedTypes, supportsType, 0, 0, 0);
59 void MediaPlayerPrivate::getSupportedTypes(HashSet<WTF::String>& types)
61 set<BlackBerry::Platform::String> supported = PlatformPlayer::allSupportedMimeTypes();
62 set<BlackBerry::Platform::String>::iterator i = supported.begin();
63 for (; i != supported.end(); i++)
67 MediaPlayer::SupportsType MediaPlayerPrivate::supportsType(const WTF::String& type, const WTF::String& codecs, const KURL& url)
69 bool isRTSP = url.protocolIs("rtsp");
71 if (!isRTSP && (type.isNull() || type.isEmpty())) {
72 LOG(Media, "MediaPlayer does not support type; type is null or empty.");
73 return MediaPlayer::IsNotSupported;
76 // spec says we should not return "probably" if the codecs string is empty
77 if (isRTSP || PlatformPlayer::mimeTypeSupported(type.ascii().data())) {
78 LOG(Media, "MediaPlayer supports type %s.", isRTSP ? "rtsp" : type.ascii().data());
79 return codecs.isEmpty() ? MediaPlayer::MayBeSupported : MediaPlayer::IsSupported;
81 LOG(Media, "MediaPlayer does not support type %s.", type.ascii().data());
82 return MediaPlayer::IsNotSupported;
85 void MediaPlayerPrivate::notifyAppActivatedEvent(bool activated)
87 PlatformPlayer::notifyAppActivatedEvent(activated);
90 void MediaPlayerPrivate::setCertificatePath(const WTF::String& caPath)
92 PlatformPlayer::setCertificatePath(caPath);
95 MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
96 : m_webCorePlayer(player)
98 , m_networkState(MediaPlayer::Empty)
99 , m_readyState(MediaPlayer::HaveNothing)
100 , m_fullscreenWebPageClient(0)
101 #if USE(ACCELERATED_COMPOSITING)
102 , m_bufferingTimer(this, &MediaPlayerPrivate::bufferingTimerFired)
103 , m_showBufferingImage(false)
105 , m_userDrivenSeekTimer(this, &MediaPlayerPrivate::userDrivenSeekTimerFired)
107 , m_lastLoadingTime(0)
108 , m_lastSeekTimePending(false)
109 , m_isAuthenticationChallenging(false)
110 , m_waitMetadataTimer(this, &MediaPlayerPrivate::waitMetadataTimerFired)
111 , m_waitMetadataPopDialogCounter(0)
115 MediaPlayerPrivate::~MediaPlayerPrivate()
117 if (m_isAuthenticationChallenging)
118 AuthenticationChallengeManager::instance()->cancelAuthenticationChallenge(this);
121 m_webCorePlayer->mediaPlayerClient()->mediaPlayerExitFullscreen();
122 #if USE(ACCELERATED_COMPOSITING)
123 // Remove media player from platform layer.
125 static_cast<VideoLayerWebKitThread*>(m_platformLayer.get())->setMediaPlayer(0);
128 if (m_platformPlayer) {
129 if (m_platformPlayer->dialogState() == PlatformPlayer::DialogShown) {
130 m_platformPlayer->setDialogState(PlatformPlayer::MediaPlayerPrivateDestroyed);
131 m_platformPlayer->stop();
133 deleteGuardedObject(m_platformPlayer);
137 void MediaPlayerPrivate::load(const WTF::String& url)
139 WTF::String modifiedUrl(url);
141 if (modifiedUrl.startsWith("local://")) {
142 KURL kurl = KURL(KURL(), modifiedUrl);
143 kurl.setProtocol("file");
144 WTF::String tempPath(BlackBerry::Platform::Settings::instance()->applicationLocalDirectory().c_str());
145 tempPath.append(kurl.path());
146 kurl.setPath(tempPath);
147 modifiedUrl = kurl.string();
149 if (modifiedUrl.startsWith("file://")) {
150 // The QNX Multimedia Framework cannot handle filenames containing URL escape sequences.
151 modifiedUrl = decodeURLEscapeSequences(modifiedUrl);
154 void* tabId = m_webCorePlayer->mediaPlayerClient()->mediaPlayerHostWindow()->platformPageClient();
155 int playerID = m_webCorePlayer->mediaPlayerClient()->mediaPlayerHostWindow()->platformPageClient()->playerID();
156 bool isVideo = m_webCorePlayer->mediaPlayerClient()->mediaPlayerIsVideo();
158 deleteGuardedObject(m_platformPlayer);
159 #if USE(ACCELERATED_COMPOSITING)
160 m_platformPlayer = PlatformPlayer::create(this, tabId, isVideo, true, modifiedUrl.utf8().data());
162 m_platformPlayer = PlatformPlayer::create(this, tabId, isVideo, false, modifiedUrl.utf8().data());
165 WTF::String cookiePairs;
167 cookiePairs = cookieManager().getCookie(KURL(ParsedURLString, url.utf8().data()), WithHttpOnlyCookies);
168 if (!cookiePairs.isEmpty() && cookiePairs.utf8().data())
169 m_platformPlayer->load(playerID, modifiedUrl.utf8().data(), m_webCorePlayer->userAgent().utf8().data(), cookiePairs.utf8().data());
171 m_platformPlayer->load(playerID, modifiedUrl.utf8().data(), m_webCorePlayer->userAgent().utf8().data(), 0);
174 void MediaPlayerPrivate::cancelLoad()
176 if (m_platformPlayer)
177 m_platformPlayer->cancelLoad();
180 void MediaPlayerPrivate::prepareToPlay()
182 if (m_platformPlayer)
183 m_platformPlayer->prepareToPlay();
186 void MediaPlayerPrivate::play()
188 if (m_platformPlayer) {
189 m_platformPlayer->play();
193 void MediaPlayerPrivate::pause()
195 if (m_platformPlayer)
196 m_platformPlayer->pause();
199 bool MediaPlayerPrivate::supportsFullscreen() const
204 IntSize MediaPlayerPrivate::naturalSize() const
206 if (!m_platformPlayer)
209 // Cannot return empty size, otherwise paint() will never get called.
210 // Also, the values here will affect the aspect ratio of the output rectangle that will
211 // be used for renderering the video, so we must take PAR into account.
212 // Now, hope that metadata has been provided before this gets called if this is a video.
213 double pixelWidth = static_cast<double>(m_platformPlayer->pixelWidth());
214 double pixelHeight = static_cast<double>(m_platformPlayer->pixelHeight());
215 if (!m_platformPlayer->pixelWidth() || !m_platformPlayer->pixelHeight())
216 pixelWidth = pixelHeight = 1.0;
218 // Use floating point arithmetic to eliminate the chance of integer
219 // overflow. PAR numbers can be 5 digits or more.
220 double adjustedSourceWidth = static_cast<double>(m_platformPlayer->sourceWidth()) * pixelWidth / pixelHeight;
221 return IntSize(static_cast<int>(adjustedSourceWidth + 0.5), m_platformPlayer->sourceHeight());
224 bool MediaPlayerPrivate::hasVideo() const
226 if (m_platformPlayer)
227 return m_platformPlayer->hasVideo();
231 bool MediaPlayerPrivate::hasAudio() const
233 if (m_platformPlayer)
234 return m_platformPlayer->hasAudio();
238 void MediaPlayerPrivate::setVisible(bool)
243 float MediaPlayerPrivate::duration() const
245 if (m_platformPlayer)
246 return m_platformPlayer->duration();
250 static const double SeekSubmissionDelay = 0.1; // Reasonable throttling value.
251 static const double ShortMediaThreshold = SeekSubmissionDelay * 2.0;
253 float MediaPlayerPrivate::currentTime() const
255 if (!m_platformPlayer)
258 // For very short media on the order of SeekSubmissionDelay we get
259 // unwanted repeats if we don't return the most up-to-date currentTime().
260 bool shortMedia = m_platformPlayer->duration() < ShortMediaThreshold;
261 return m_userDrivenSeekTimer.isActive() && !shortMedia ? m_lastSeekTime: m_platformPlayer->currentTime();
264 void MediaPlayerPrivate::seek(float time)
266 if (!m_platformPlayer)
269 m_lastSeekTime = time;
270 m_lastSeekTimePending = true;
271 if (!m_userDrivenSeekTimer.isActive())
272 userDrivenSeekTimerFired(0);
275 void MediaPlayerPrivate::userDrivenSeekTimerFired(Timer<MediaPlayerPrivate>*)
277 if (m_lastSeekTimePending) {
278 m_platformPlayer->seek(m_lastSeekTime);
279 m_lastSeekTimePending = false;
280 m_userDrivenSeekTimer.startOneShot(SeekSubmissionDelay);
284 bool MediaPlayerPrivate::seeking() const
289 void MediaPlayerPrivate::setRate(float rate)
291 if (m_platformPlayer)
292 m_platformPlayer->setRate(rate);
295 bool MediaPlayerPrivate::paused() const
297 if (m_platformPlayer)
298 return m_platformPlayer->paused();
302 void MediaPlayerPrivate::setVolume(float volume)
304 if (m_platformPlayer)
305 m_platformPlayer->setVolume(volume);
308 void MediaPlayerPrivate::setMuted(bool muted)
310 if (m_platformPlayer)
311 m_platformPlayer->setMuted(muted);
314 bool MediaPlayerPrivate::muted() const
316 if (m_platformPlayer)
317 return m_platformPlayer->muted();
321 MediaPlayer::NetworkState MediaPlayerPrivate::networkState() const
323 return m_networkState;
326 MediaPlayer::ReadyState MediaPlayerPrivate::readyState() const
331 float MediaPlayerPrivate::maxTimeSeekable() const
333 if (m_platformPlayer)
334 return m_platformPlayer->maxTimeSeekable();
338 PassRefPtr<TimeRanges> MediaPlayerPrivate::buffered() const
340 if (!m_platformPlayer)
341 return TimeRanges::create();
343 RefPtr<TimeRanges> timeRanges = TimeRanges::create();
344 if (float bufferLoaded = m_platformPlayer->bufferLoaded())
345 timeRanges->add(0, bufferLoaded);
346 return timeRanges.release();
349 bool MediaPlayerPrivate::didLoadingProgress() const
351 if (!m_platformPlayer)
354 float bufferLoaded = m_platformPlayer->bufferLoaded();
355 if (bufferLoaded == m_lastLoadingTime)
358 m_lastLoadingTime = bufferLoaded;
362 void MediaPlayerPrivate::setSize(const IntSize&)
367 void MediaPlayerPrivate::paint(GraphicsContext* context, const IntRect& rect)
369 if (!m_platformPlayer)
372 #if USE(ACCELERATED_COMPOSITING)
373 if (supportsAcceleratedRendering()) {
374 // Only process paint calls coming via the accelerated compositing code
375 // path, where we get called with a null graphics context. See
376 // LayerCompositingThread::drawTextures(). Ignore calls from the regular
379 m_platformPlayer->notifyOutputUpdate(BlackBerry::Platform::IntRect(rect.x(), rect.y(), rect.width(), rect.height()));
385 paintCurrentFrameInContext(context, rect);
388 void MediaPlayerPrivate::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& rect)
390 if (!hasVideo() || context->paintingDisabled() || !m_webCorePlayer->visible())
393 BlackBerry::Platform::Graphics::Drawable* dst = context->platformContext();
395 BlackBerry::Platform::IntRect platformRect(rect.x(), rect.y(), rect.width(), rect.height());
396 IntRect clippedRect = m_webCorePlayer->mediaPlayerClient()->mediaPlayerWindowClipRect();
397 BlackBerry::Platform::IntRect platformWindowClipRect(clippedRect.x(), clippedRect.y(), clippedRect.width(), clippedRect.height());
398 m_platformPlayer->paint(dst, platformRect, platformWindowClipRect);
401 bool MediaPlayerPrivate::hasAvailableVideoFrame() const
403 if (m_platformPlayer)
404 return m_platformPlayer->hasAvailableVideoFrame();
408 bool MediaPlayerPrivate::hasSingleSecurityOrigin() const
413 MediaPlayer::MovieLoadType MediaPlayerPrivate::movieLoadType() const
415 if (m_platformPlayer)
416 return static_cast<MediaPlayer::MovieLoadType>(m_platformPlayer->movieLoadType());
417 return MediaPlayer::Unknown;
420 void MediaPlayerPrivate::prepareForRendering()
422 if (m_platformPlayer)
423 m_platformPlayer->prepareForRendering();
426 void MediaPlayerPrivate::resizeSourceDimensions()
428 if (!m_webCorePlayer)
431 if (!m_webCorePlayer->mediaPlayerClient()->mediaPlayerIsVideo())
434 // If we don't know what the width and height of the video source is, then we need to set it to something sane.
435 if (m_platformPlayer->sourceWidth() && m_platformPlayer->sourceHeight())
438 LayoutRect rect = m_webCorePlayer->mediaPlayerClient()->mediaPlayerContentBoxRect();
439 m_platformPlayer->setSourceDimension(rect.width().toUnsigned(), rect.height().toUnsigned());
442 void MediaPlayerPrivate::setFullscreenWebPageClient(BlackBerry::WebKit::WebPageClient* client)
444 if (m_fullscreenWebPageClient == client)
447 m_fullscreenWebPageClient = client;
448 m_platformPlayer->toggleFullscreen(client);
450 // The following repaint is needed especially if video is paused and
451 // fullscreen is exiting, so that a MediaPlayerPrivate::paint() is
452 // triggered and the code in outputUpdate() sets the correct window
455 m_webCorePlayer->repaint();
458 BlackBerry::Platform::Graphics::Window* MediaPlayerPrivate::getWindow()
460 return m_platformPlayer->getWindow();
463 BlackBerry::Platform::Graphics::Window* MediaPlayerPrivate::getPeerWindow(const char* uniqueID) const
465 return m_platformPlayer->getPeerWindow(uniqueID);
468 BlackBerry::Platform::IntRect MediaPlayerPrivate::getWindowScreenRect() const
470 unsigned x, y, width, height;
471 m_platformPlayer->getWindowPosition(x, y, width, height);
472 return BlackBerry::Platform::IntRect(x, y, width, height);
475 const char* MediaPlayerPrivate::mmrContextName()
477 return m_platformPlayer->mmrContextName();
480 float MediaPlayerPrivate::percentLoaded()
482 if (!m_platformPlayer->duration())
486 RefPtr<TimeRanges> timeRanges = this->buffered();
487 for (unsigned i = 0; i < timeRanges->length(); ++i) {
488 ExceptionCode ignoredException;
489 float start = timeRanges->start(i, ignoredException);
490 float end = timeRanges->end(i, ignoredException);
491 buffered += end - start;
494 float loaded = buffered / m_platformPlayer->duration();
498 unsigned MediaPlayerPrivate::sourceWidth()
500 return m_platformPlayer->sourceWidth();
503 unsigned MediaPlayerPrivate::sourceHeight()
505 return m_platformPlayer->sourceHeight();
508 void MediaPlayerPrivate::setAllowPPSVolumeUpdates(bool allow)
510 if (m_platformPlayer)
511 return m_platformPlayer->setAllowPPSVolumeUpdates(allow);
514 void MediaPlayerPrivate::updateStates()
516 MediaPlayer::NetworkState oldNetworkState = m_networkState;
517 MediaPlayer::ReadyState oldReadyState = m_readyState;
519 PlatformPlayer::Error currentError = m_platformPlayer->error();
521 if (currentError != PlatformPlayer::MediaOK) {
522 m_readyState = MediaPlayer::HaveNothing;
523 if (currentError == PlatformPlayer::MediaDecodeError)
524 m_networkState = MediaPlayer::DecodeError;
525 else if (currentError == PlatformPlayer::MediaMetaDataError
526 || currentError == PlatformPlayer::MediaAudioReceiveError
527 || currentError == PlatformPlayer::MediaVideoReceiveError)
528 m_networkState = MediaPlayer::NetworkError;
530 switch (m_platformPlayer->mediaState()) {
531 case PlatformPlayer::MMRPlayStateIdle:
532 m_networkState = MediaPlayer::Idle;
534 case PlatformPlayer::MMRPlayStatePlaying:
535 m_networkState = MediaPlayer::Loading;
537 case PlatformPlayer::MMRPlayStateStopped:
538 m_networkState = MediaPlayer::Idle;
540 case PlatformPlayer::MMRPlayStateUnknown:
545 switch (m_platformPlayer->state()) {
546 case PlatformPlayer::MP_STATE_IDLE:
548 m_webCorePlayer->mediaPlayerClient()->mediaPlayerExitFullscreen();
550 case PlatformPlayer::MP_STATE_ACTIVE:
552 case PlatformPlayer::MP_STATE_UNSUPPORTED:
557 if ((duration() || movieLoadType() == MediaPlayer::LiveStream)
558 && m_readyState != MediaPlayer::HaveEnoughData)
559 m_readyState = MediaPlayer::HaveEnoughData;
562 if (m_readyState != oldReadyState)
563 m_webCorePlayer->readyStateChanged();
564 if (m_networkState != oldNetworkState)
565 m_webCorePlayer->networkStateChanged();
568 // IPlatformPlayerListener callbacks implementation
569 void MediaPlayerPrivate::onStateChanged(PlatformPlayer::MpState)
574 void MediaPlayerPrivate::onMediaStatusChanged(PlatformPlayer::MMRPlayState)
579 void MediaPlayerPrivate::onError(PlatformPlayer::Error type)
584 void MediaPlayerPrivate::onDurationChanged(float duration)
587 m_webCorePlayer->durationChanged();
590 void MediaPlayerPrivate::onTimeChanged(float)
592 m_webCorePlayer->timeChanged();
595 void MediaPlayerPrivate::onPauseStateChanged()
600 // Paused state change not due to local controller.
601 if (m_platformPlayer->isPaused())
602 m_webCorePlayer->mediaPlayerClient()->mediaPlayerPause();
604 // The HMI fullscreen widget has resumed play. Check if the
605 // pause timeout occurred.
606 m_platformPlayer->processPauseTimeoutIfNecessary();
607 m_webCorePlayer->mediaPlayerClient()->mediaPlayerPlay();
611 void MediaPlayerPrivate::onRateChanged(float)
613 m_webCorePlayer->rateChanged();
616 void MediaPlayerPrivate::onVolumeChanged(float volume)
618 m_webCorePlayer->volumeChanged(volume);
621 void MediaPlayerPrivate::onRepaint()
623 m_webCorePlayer->repaint();
626 void MediaPlayerPrivate::onSizeChanged()
628 resizeSourceDimensions();
630 m_webCorePlayer->sizeChanged();
633 void MediaPlayerPrivate::onPlayNotified()
635 m_webCorePlayer->mediaPlayerClient()->mediaPlayerPlay();
638 void MediaPlayerPrivate::onPauseNotified()
640 m_webCorePlayer->mediaPlayerClient()->mediaPlayerPause();
643 static const int popupDialogInterval = 10;
644 static const double checkMetadataReadyInterval = 0.5;
645 void MediaPlayerPrivate::onWaitMetadataNotified(bool hasFinished, int timeWaited)
648 if (!m_waitMetadataTimer.isActive()) {
649 // Make sure to popup dialog every 10 seconds after metadata start to load.
650 // This should be set only once at the first time when user press the play button.
651 m_waitMetadataPopDialogCounter = static_cast<int>(timeWaited / checkMetadataReadyInterval);
652 m_waitMetadataTimer.startOneShot(checkMetadataReadyInterval);
654 } else if (m_waitMetadataTimer.isActive()) {
655 m_waitMetadataTimer.stop();
656 m_waitMetadataPopDialogCounter = 0;
660 void MediaPlayerPrivate::waitMetadataTimerFired(Timer<MediaPlayerPrivate>*)
662 if (m_platformPlayer->isMetadataReady()) {
663 m_waitMetadataPopDialogCounter = 0;
664 m_platformPlayer->playWithMetadataReady();
668 static const int hitTimeToPopupDialog = static_cast<int>(popupDialogInterval / checkMetadataReadyInterval);
669 m_waitMetadataPopDialogCounter++;
670 if (m_waitMetadataPopDialogCounter < hitTimeToPopupDialog) {
671 m_waitMetadataTimer.startOneShot(checkMetadataReadyInterval);
674 m_waitMetadataPopDialogCounter = 0;
676 PlatformPlayer::DialogResult wait = m_platformPlayer->showErrorDialog(PlatformPlayer::MediaMetaDataTimeoutError);
677 if (wait == PlatformPlayer::DialogEmergencyExit)
679 if (wait == PlatformPlayer::DialogResponse0)
682 if (m_platformPlayer->isMetadataReady()) {
683 m_platformPlayer->playWithMetadataReady();
685 m_waitMetadataTimer.startOneShot(checkMetadataReadyInterval);
689 #if USE(ACCELERATED_COMPOSITING)
690 void MediaPlayerPrivate::onBuffering(bool flag)
696 static ProtectionSpace generateProtectionSpaceFromMMRAuthChallenge(const MMRAuthChallenge& authChallenge)
698 KURL url(ParsedURLString, WTF::String(authChallenge.url().c_str()));
699 ASSERT(url.isValid());
701 return ProtectionSpace(url.host(), url.port(),
702 static_cast<ProtectionSpaceServerType>(authChallenge.serverType()),
703 authChallenge.realm().c_str(),
704 static_cast<ProtectionSpaceAuthenticationScheme>(authChallenge.authScheme()));
707 void MediaPlayerPrivate::onAuthenticationNeeded(MMRAuthChallenge& authChallenge)
709 KURL url(ParsedURLString, WTF::String(authChallenge.url().c_str()));
713 ProtectionSpace protectionSpace = generateProtectionSpaceFromMMRAuthChallenge(authChallenge);
714 Credential credential = CredentialStorage::get(protectionSpace);
715 if (!credential.isEmpty()) {
716 notifyChallengeResult(url, protectionSpace, AuthenticationChallengeSuccess, credential);
720 m_isAuthenticationChallenging = true;
721 AuthenticationChallengeManager::instance()->authenticationChallenge(url, protectionSpace, credential,
722 this, m_webCorePlayer->mediaPlayerClient()->mediaPlayerHostWindow()->platformPageClient());
725 void MediaPlayerPrivate::notifyChallengeResult(const KURL& url, const ProtectionSpace& protectionSpace, AuthenticationChallengeResult result, const Credential& credential)
727 m_isAuthenticationChallenging = false;
729 if (result != AuthenticationChallengeSuccess || !url.isValid())
732 m_platformPlayer->reloadWithCredential(credential.user().utf8(WTF::String::StrictConversion).data(),
733 credential.password().utf8(WTF::String::StrictConversion).data(),
734 static_cast<MMRAuthChallenge::CredentialPersistence>(credential.persistence()));
737 void MediaPlayerPrivate::onAuthenticationAccepted(const MMRAuthChallenge& authChallenge) const
739 KURL url(ParsedURLString, WTF::String(authChallenge.url().c_str()));
743 ProtectionSpace protectionSpace = generateProtectionSpaceFromMMRAuthChallenge(authChallenge);
744 Credential savedCredential = CredentialStorage::get(protectionSpace);
745 if (savedCredential.isEmpty())
746 CredentialStorage::set(Credential(authChallenge.username().c_str(), authChallenge.password().c_str(), static_cast<CredentialPersistence>(authChallenge.persistence())), protectionSpace, url);
749 int MediaPlayerPrivate::onShowErrorDialog(PlatformPlayer::Error type)
751 using namespace BlackBerry::WebKit;
753 WebPageClient::AlertType atype;
755 case PlatformPlayer::MediaOK:
756 atype = WebPageClient::MediaOK;
758 case PlatformPlayer::MediaDecodeError:
759 atype = WebPageClient::MediaDecodeError;
761 case PlatformPlayer::MediaMetaDataError:
762 atype = WebPageClient::MediaMetaDataError;
764 case PlatformPlayer::MediaMetaDataTimeoutError:
765 atype = WebPageClient::MediaMetaDataTimeoutError;
767 case PlatformPlayer::MediaNoMetaDataError:
768 atype = WebPageClient::MediaNoMetaDataError;
770 case PlatformPlayer::MediaVideoReceiveError:
771 atype = WebPageClient::MediaVideoReceiveError;
773 case PlatformPlayer::MediaAudioReceiveError:
774 atype = WebPageClient::MediaAudioReceiveError;
776 case PlatformPlayer::MediaInvalidError:
777 atype = WebPageClient::MediaInvalidError;
780 LOG(Media, "Alert type does not exist.");
783 return m_webCorePlayer->mediaPlayerClient()->mediaPlayerHostWindow()->platformPageClient()->showAlertDialog(atype);
786 static WebMediaStreamSource toWebMediaStreamSource(MediaStreamSource* src)
788 return WebMediaStreamSource(src->id().utf8().data(), static_cast<WebMediaStreamSource::Type>(src->type()), src->name().utf8().data());
791 static WebMediaStreamDescriptor toWebMediaStreamDescriptor(MediaStreamDescriptor* d)
793 vector<WebMediaStreamSource> audioSources;
794 for (size_t i = 0; i < d->numberOfAudioComponents(); i++)
795 audioSources.push_back(toWebMediaStreamSource(d->audioComponent(i)->source()));
797 vector<WebMediaStreamSource> videoSources;
798 for (size_t i = 0; i < d->numberOfVideoComponents(); i++)
799 videoSources.push_back(toWebMediaStreamSource(d->videoComponent(i)->source()));
801 return WebMediaStreamDescriptor(d->label().utf8().data(), audioSources, videoSources);
804 WebMediaStreamDescriptor MediaPlayerPrivate::lookupMediaStream(const BlackBerry::Platform::String& url)
806 MediaStreamDescriptor* descriptor = MediaStreamRegistry::registry().lookupMediaStreamDescriptor(WTF::String::fromUTF8(url.c_str()));
808 return WebMediaStreamDescriptor();
810 return toWebMediaStreamDescriptor(descriptor);
813 BlackBerry::Platform::Graphics::Window* MediaPlayerPrivate::platformWindow()
815 return m_webCorePlayer->mediaPlayerClient()->mediaPlayerHostWindow()->platformPageClient()->platformWindow();
818 bool MediaPlayerPrivate::isProcessingUserGesture() const
820 return m_webCorePlayer->mediaPlayerClient()->mediaPlayerIsProcessingUserGesture();
823 bool MediaPlayerPrivate::isFullscreen() const
825 return m_fullscreenWebPageClient;
828 bool MediaPlayerPrivate::isElementPaused() const
830 return m_webCorePlayer->mediaPlayerClient()->mediaPlayerIsPaused();
833 bool MediaPlayerPrivate::isTabVisible() const
835 return m_webCorePlayer->mediaPlayerClient()->mediaPlayerHostWindow()->platformPageClient()->isVisible();
838 bool MediaPlayerPrivate::supportsAcceleratedRendering() const
840 if (m_platformPlayer)
841 return m_platformPlayer->supportsAcceleratedRendering();
845 #if USE(ACCELERATED_COMPOSITING)
846 static const double BufferingAnimationDelay = 1.0 / 24;
847 static unsigned* s_bufferingImageData = 0;
848 static int s_bufferingImageWidth = 0;
849 static int s_bufferingImageHeight = 0;
851 PlatformMedia MediaPlayerPrivate::platformMedia() const
854 pm.type = PlatformMedia::QNXMediaPlayerType;
855 pm.media.qnxMediaPlayer = const_cast<MediaPlayerPrivate*>(this);
859 PlatformLayer* MediaPlayerPrivate::platformLayer() const
862 return m_platformLayer.get();
866 static void loadBufferingImageData()
868 static bool loaded = false;
870 static Image* bufferingIcon = Image::loadPlatformResource("vidbuffer").leakRef();
872 NativeImagePtr nativeImage = bufferingIcon->nativeImageForCurrentFrame();
877 s_bufferingImageWidth = bufferingIcon->width();
878 s_bufferingImageHeight = bufferingIcon->height();
879 int bufSize = bufferingIcon->decodedSize();
880 s_bufferingImageData = static_cast<unsigned*>(malloc(bufSize));
882 nativeImage->readPixels(s_bufferingImageData, s_bufferingImageWidth * s_bufferingImageHeight);
884 bufferingIcon->deref();
888 void MediaPlayerPrivate::bufferingTimerFired(Timer<MediaPlayerPrivate>*)
890 if (m_showBufferingImage) {
891 if (!isFullscreen() && m_platformLayer)
892 m_platformLayer->setNeedsDisplay();
893 m_bufferingTimer.startOneShot(BufferingAnimationDelay);
897 void MediaPlayerPrivate::setBuffering(bool buffering)
899 if (!m_webCorePlayer || !m_webCorePlayer->mediaPlayerClient() || !m_webCorePlayer->mediaPlayerClient()->mediaPlayerIsVideo())
900 buffering = false; // Buffering animation not visible for audio.
902 if (buffering != m_showBufferingImage) {
903 m_showBufferingImage = buffering;
905 loadBufferingImageData();
906 m_bufferingTimer.startOneShot(BufferingAnimationDelay);
908 m_bufferingTimer.stop();
911 m_platformLayer->setNeedsDisplay();
915 static unsigned allocateTextureId()
918 glGenTextures(1, &texid);
919 glBindTexture(GL_TEXTURE_2D, texid);
920 // Do basic linear filtering on resize.
921 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
922 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
923 // NPOT textures in GL ES only work when the wrap mode is set to GL_CLAMP_TO_EDGE.
924 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
925 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
929 void MediaPlayerPrivate::drawBufferingAnimation(const TransformationMatrix& matrix, const Graphics::GLES2Program& program)
931 if (m_showBufferingImage && s_bufferingImageData && !isFullscreen()) {
932 TransformationMatrix renderMatrix = matrix;
934 // Rotate the buffering indicator so that it takes 1 second to do 1 revolution.
936 clock_gettime(CLOCK_REALTIME, &time);
937 renderMatrix.rotate(time.tv_nsec / 1000000000.0 * 360.0);
939 static bool initialized = false;
940 static unsigned texId = allocateTextureId();
941 glBindTexture(GL_TEXTURE_2D, texId);
944 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, s_bufferingImageWidth, s_bufferingImageHeight,
945 0, GL_RGBA, GL_UNSIGNED_BYTE, s_bufferingImageData);
946 free(s_bufferingImageData);
949 float texcoords[] = { 0, 0, 0, 1, 1, 1, 1, 0 };
950 FloatPoint vertices[4];
951 float bx = s_bufferingImageWidth / 2.0;
952 float by = s_bufferingImageHeight / 2.0;
953 vertices[0] = renderMatrix.mapPoint(FloatPoint(-bx, -by));
954 vertices[1] = renderMatrix.mapPoint(FloatPoint(-bx, by));
955 vertices[2] = renderMatrix.mapPoint(FloatPoint(bx, by));
956 vertices[3] = renderMatrix.mapPoint(FloatPoint(bx, -by));
959 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
960 glUniform1f(program.opacityLocation(), 1.0);
961 glVertexAttribPointer(program.positionLocation(), 2, GL_FLOAT, GL_FALSE, 0, vertices);
962 glVertexAttribPointer(program.texCoordLocation(), 2, GL_FLOAT, GL_FALSE, 0, texcoords);
963 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
968 void MediaPlayerPrivate::onConditionallyEnterFullscreen()
970 Document* owningDocument = m_webCorePlayer->mediaPlayerClient()->mediaPlayerOwningDocument();
971 BlackBerry::Platform::DeviceInfo* info = BlackBerry::Platform::DeviceInfo::instance();
973 // Don't allow video in <embed> and <object> containers to go fullscreen
974 // on play because this does not currently work. Detect this by checking
975 // for MediaDocument with a parent document.
976 if (owningDocument->isMediaDocument() && owningDocument->parentDocument())
979 if (info->isMobile()) {
980 // This is a mobile device (small screen), not a tablet, so we
981 // enter fullscreen video on user-initiated plays.
982 bool nothingIsFullscreen = !m_webCorePlayer->mediaPlayerClient()->mediaPlayerIsFullscreen();
983 #if ENABLE(FULLSCREEN_API)
984 if (owningDocument->webkitIsFullScreen())
985 nothingIsFullscreen = false;
987 if (nothingIsFullscreen)
988 m_webCorePlayer->mediaPlayerClient()->mediaPlayerEnterFullscreen();
992 void MediaPlayerPrivate::onExitFullscreen()
994 if (m_webCorePlayer->mediaPlayerClient()->mediaPlayerIsFullscreen())
995 m_webCorePlayer->mediaPlayerClient()->mediaPlayerExitFullscreen();
998 void MediaPlayerPrivate::onCreateHolePunchRect()
1000 #if USE(ACCELERATED_COMPOSITING)
1001 // Create platform layer for video (create hole punch rect).
1002 if (!m_platformLayer && supportsAcceleratedRendering()) {
1003 m_showBufferingImage = false;
1004 m_platformLayer = VideoLayerWebKitThread::create(m_webCorePlayer);
1009 void MediaPlayerPrivate::onDestroyHolePunchRect()
1011 #if USE(ACCELERATED_COMPOSITING)
1012 setBuffering(false);
1013 // Remove media player from platform layer (remove hole punch rect).
1014 if (m_platformLayer) {
1015 static_cast<VideoLayerWebKitThread*>(m_platformLayer.get())->setMediaPlayer(0);
1016 m_platformLayer.clear();
1021 } // namespace WebCore
1023 #endif // ENABLE(VIDEO)