Index: Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp |
diff --git a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp |
deleted file mode 100644 |
index df18473a6f0c588cd8f2fc0bc5dd9f15cdf42126..0000000000000000000000000000000000000000 |
--- a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp |
+++ /dev/null |
@@ -1,1268 +0,0 @@ |
-/* |
- * Copyright (C) 2007, 2008, 2009, 2010, 2011 Apple, Inc. All rights reserved. |
- * |
- * Redistribution and use in source and binary forms, with or without |
- * modification, are permitted provided that the following conditions |
- * are met: |
- * 1. Redistributions of source code must retain the above copyright |
- * notice, this list of conditions and the following disclaimer. |
- * 2. Redistributions in binary form must reproduce the above copyright |
- * notice, this list of conditions and the following disclaimer in the |
- * documentation and/or other materials provided with the distribution. |
- * |
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
- */ |
- |
-#include "config.h" |
- |
-#if ENABLE(VIDEO) |
-#include "MediaPlayerPrivateQuickTimeVisualContext.h" |
- |
-#include "Cookie.h" |
-#include "CookieJar.h" |
-#include "DocumentLoader.h" |
-#include "Frame.h" |
-#include "FrameView.h" |
-#include "GraphicsContext.h" |
-#include "KURL.h" |
-#include "MediaPlayerPrivateTaskTimer.h" |
-#include "Page.h" |
-#include "QTCFDictionary.h" |
-#include "QTDecompressionSession.h" |
-#include "QTMovie.h" |
-#include "QTMovieTask.h" |
-#include "QTMovieVisualContext.h" |
-#include "ScrollView.h" |
-#include "Settings.h" |
-#include "SoftLinking.h" |
-#include "TimeRanges.h" |
-#include "Timer.h" |
-#include <AssertMacros.h> |
-#include <CoreGraphics/CGAffineTransform.h> |
-#include <CoreGraphics/CGContext.h> |
-#include <QuartzCore/CATransform3D.h> |
-#include <Wininet.h> |
-#include <wtf/CurrentTime.h> |
-#include <wtf/HashSet.h> |
-#include <wtf/MainThread.h> |
-#include <wtf/MathExtras.h> |
-#include <wtf/StdLibExtras.h> |
-#include <wtf/text/StringBuilder.h> |
-#include <wtf/text/StringHash.h> |
- |
-#if USE(ACCELERATED_COMPOSITING) |
-#include "PlatformCALayer.h" |
-#include "WKCAImageQueue.h" |
-#endif |
- |
-using namespace std; |
- |
-namespace WebCore { |
- |
-static CGImageRef CreateCGImageFromPixelBuffer(QTPixelBuffer buffer); |
-static bool requiredDllsAvailable(); |
- |
-SOFT_LINK_LIBRARY(Wininet) |
-SOFT_LINK(Wininet, InternetSetCookieExW, DWORD, WINAPI, (LPCWSTR lpszUrl, LPCWSTR lpszCookieName, LPCWSTR lpszCookieData, DWORD dwFlags, DWORD_PTR dwReserved), (lpszUrl, lpszCookieName, lpszCookieData, dwFlags, dwReserved)) |
- |
-// Interface declaration for MediaPlayerPrivateQuickTimeVisualContext's QTMovieClient aggregate |
-class MediaPlayerPrivateQuickTimeVisualContext::MovieClient : public QTMovieClient { |
-public: |
- MovieClient(MediaPlayerPrivateQuickTimeVisualContext* parent) : m_parent(parent) {} |
- virtual ~MovieClient() { m_parent = 0; } |
- virtual void movieEnded(QTMovie*); |
- virtual void movieLoadStateChanged(QTMovie*); |
- virtual void movieTimeChanged(QTMovie*); |
-private: |
- MediaPlayerPrivateQuickTimeVisualContext* m_parent; |
-}; |
- |
-#if USE(ACCELERATED_COMPOSITING) |
-class MediaPlayerPrivateQuickTimeVisualContext::LayerClient : public PlatformCALayerClient { |
-public: |
- LayerClient(MediaPlayerPrivateQuickTimeVisualContext* parent) : m_parent(parent) {} |
- virtual ~LayerClient() { m_parent = 0; } |
- |
-private: |
- virtual void platformCALayerLayoutSublayersOfLayer(PlatformCALayer*); |
- virtual bool platformCALayerRespondsToLayoutChanges() const { return true; } |
- |
- virtual void platformCALayerAnimationStarted(CFTimeInterval beginTime) { } |
- virtual GraphicsLayer::CompositingCoordinatesOrientation platformCALayerContentsOrientation() const { return GraphicsLayer::CompositingCoordinatesBottomUp; } |
- virtual void platformCALayerPaintContents(GraphicsContext&, const IntRect& inClip) { } |
- virtual bool platformCALayerShowDebugBorders() const { return false; } |
- virtual bool platformCALayerShowRepaintCounter(PlatformCALayer*) const { return false; } |
- virtual int platformCALayerIncrementRepaintCount() { return 0; } |
- |
- virtual bool platformCALayerContentsOpaque() const { return false; } |
- virtual bool platformCALayerDrawsContent() const { return false; } |
- virtual void platformCALayerLayerDidDisplay(PlatformLayer*) { } |
- virtual void platformCALayerDidCreateTiles(const Vector<FloatRect>&) { } |
- virtual float platformCALayerDeviceScaleFactor() { return 1; } |
- |
- MediaPlayerPrivateQuickTimeVisualContext* m_parent; |
-}; |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::LayerClient::platformCALayerLayoutSublayersOfLayer(PlatformCALayer* layer) |
-{ |
- ASSERT(m_parent); |
- ASSERT(m_parent->m_transformLayer == layer); |
- |
- FloatSize parentSize = layer->bounds().size(); |
- FloatSize naturalSize = m_parent->naturalSize(); |
- |
- // Calculate the ratio of these two sizes and use that ratio to scale the qtVideoLayer: |
- FloatSize ratio(parentSize.width() / naturalSize.width(), parentSize.height() / naturalSize.height()); |
- |
- int videoWidth = 0; |
- int videoHeight = 0; |
- m_parent->m_movie->getNaturalSize(videoWidth, videoHeight); |
- FloatRect videoBounds(0, 0, videoWidth * ratio.width(), videoHeight * ratio.height()); |
- FloatPoint3D videoAnchor = m_parent->m_qtVideoLayer->anchorPoint(); |
- |
- // Calculate the new position based on the parent's size: |
- FloatPoint position(parentSize.width() * 0.5 - videoBounds.width() * (0.5 - videoAnchor.x()), |
- parentSize.height() * 0.5 - videoBounds.height() * (0.5 - videoAnchor.y())); |
- |
- m_parent->m_qtVideoLayer->setBounds(videoBounds); |
- m_parent->m_qtVideoLayer->setPosition(position); |
-} |
-#endif |
- |
-class MediaPlayerPrivateQuickTimeVisualContext::VisualContextClient : public QTMovieVisualContextClient { |
-public: |
- VisualContextClient(MediaPlayerPrivateQuickTimeVisualContext* parent) : m_parent(parent) {} |
- virtual ~VisualContextClient() { m_parent = 0; } |
- void imageAvailableForTime(const QTCVTimeStamp*); |
- static void retrieveCurrentImageProc(void*); |
-private: |
- MediaPlayerPrivateQuickTimeVisualContext* m_parent; |
-}; |
- |
-PassOwnPtr<MediaPlayerPrivateInterface> MediaPlayerPrivateQuickTimeVisualContext::create(MediaPlayer* player) |
-{ |
- return adoptPtr(new MediaPlayerPrivateQuickTimeVisualContext(player)); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::registerMediaEngine(MediaEngineRegistrar registrar) |
-{ |
- if (isAvailable()) |
- registrar(create, getSupportedTypes, supportsType, 0, 0, 0); |
-} |
- |
-MediaPlayerPrivateQuickTimeVisualContext::MediaPlayerPrivateQuickTimeVisualContext(MediaPlayer* player) |
- : m_player(player) |
- , m_seekTo(-1) |
- , m_seekTimer(this, &MediaPlayerPrivateQuickTimeVisualContext::seekTimerFired) |
- , m_visualContextTimer(this, &MediaPlayerPrivateQuickTimeVisualContext::visualContextTimerFired) |
- , m_networkState(MediaPlayer::Empty) |
- , m_readyState(MediaPlayer::HaveNothing) |
- , m_enabledTrackCount(0) |
- , m_totalTrackCount(0) |
- , m_hasUnsupportedTracks(false) |
- , m_startedPlaying(false) |
- , m_isStreaming(false) |
- , m_visible(false) |
- , m_newFrameAvailable(false) |
- , m_movieClient(adoptPtr(new MediaPlayerPrivateQuickTimeVisualContext::MovieClient(this))) |
-#if USE(ACCELERATED_COMPOSITING) |
- , m_layerClient(adoptPtr(new MediaPlayerPrivateQuickTimeVisualContext::LayerClient(this))) |
- , m_movieTransform(CGAffineTransformIdentity) |
-#endif |
- , m_visualContextClient(adoptPtr(new MediaPlayerPrivateQuickTimeVisualContext::VisualContextClient(this))) |
- , m_delayingLoad(false) |
- , m_privateBrowsing(false) |
- , m_preload(MediaPlayer::Auto) |
- , m_maxTimeLoadedAtLastDidLoadingProgress(0) |
-{ |
-} |
- |
-MediaPlayerPrivateQuickTimeVisualContext::~MediaPlayerPrivateQuickTimeVisualContext() |
-{ |
- tearDownVideoRendering(); |
- cancelCallOnMainThread(&VisualContextClient::retrieveCurrentImageProc, this); |
-} |
- |
-bool MediaPlayerPrivateQuickTimeVisualContext::supportsFullscreen() const |
-{ |
-#if USE(ACCELERATED_COMPOSITING) |
- Document* document = m_player->mediaPlayerClient()->mediaPlayerOwningDocument(); |
- if (document && document->settings()) |
- return document->settings()->acceleratedCompositingEnabled(); |
-#endif |
- return false; |
-} |
- |
-PlatformMedia MediaPlayerPrivateQuickTimeVisualContext::platformMedia() const |
-{ |
- PlatformMedia p; |
- p.type = PlatformMedia::QTMovieVisualContextType; |
- p.media.qtMovieVisualContext = m_visualContext.get(); |
- return p; |
-} |
-#if USE(ACCELERATED_COMPOSITING) |
- |
-PlatformLayer* MediaPlayerPrivateQuickTimeVisualContext::platformLayer() const |
-{ |
- return m_transformLayer ? m_transformLayer->platformLayer() : 0; |
-} |
-#endif |
- |
-String MediaPlayerPrivateQuickTimeVisualContext::rfc2616DateStringFromTime(CFAbsoluteTime time) |
-{ |
- static const char* const dayStrings[] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }; |
- static const char* const monthStrings[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; |
- static const CFStringRef dateFormatString = CFSTR("%s, %02d %s %04d %02d:%02d:%02d GMT"); |
- static CFTimeZoneRef gmtTimeZone; |
- if (!gmtTimeZone) |
- gmtTimeZone = CFTimeZoneCopyDefault(); |
- |
- CFGregorianDate dateValue = CFAbsoluteTimeGetGregorianDate(time, gmtTimeZone); |
- if (!CFGregorianDateIsValid(dateValue, kCFGregorianAllUnits)) |
- return String(); |
- |
- time = CFGregorianDateGetAbsoluteTime(dateValue, gmtTimeZone); |
- SInt32 day = CFAbsoluteTimeGetDayOfWeek(time, 0); |
- |
- RetainPtr<CFStringRef> dateCFString(AdoptCF, CFStringCreateWithFormat(0, 0, dateFormatString, dayStrings[day - 1], dateValue.day, |
- monthStrings[dateValue.month - 1], dateValue.year, dateValue.hour, dateValue.minute, (int)dateValue.second)); |
- return dateCFString.get(); |
-} |
- |
-static void addCookieParam(StringBuilder& cookieBuilder, const String& name, const String& value) |
-{ |
- if (name.isEmpty()) |
- return; |
- |
- // If this isn't the first parameter added, terminate the previous one. |
- if (cookieBuilder.length()) |
- cookieBuilder.append("; "); |
- |
- // Add parameter name, and value if there is one. |
- cookieBuilder.append(name); |
- if (!value.isEmpty()) { |
- cookieBuilder.append('='); |
- cookieBuilder.append(value); |
- } |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::setUpCookiesForQuickTime(const String& url) |
-{ |
- // WebCore loaded the page with the movie URL with CFNetwork but QuickTime will |
- // use WinINet to download the movie, so we need to copy any cookies needed to |
- // download the movie into WinInet before asking QuickTime to open it. |
- Document* document = m_player->mediaPlayerClient()->mediaPlayerOwningDocument(); |
- Frame* frame = document ? document->frame() : 0; |
- if (!frame || !frame->page() || !frame->page()->settings()->cookieEnabled()) |
- return; |
- |
- KURL movieURL = KURL(KURL(), url); |
- Vector<Cookie> documentCookies; |
- if (!getRawCookies(frame->document(), movieURL, documentCookies)) |
- return; |
- |
- for (size_t ndx = 0; ndx < documentCookies.size(); ndx++) { |
- const Cookie& cookie = documentCookies[ndx]; |
- |
- if (cookie.name.isEmpty()) |
- continue; |
- |
- // Build up the cookie string with as much information as we can get so WinINet |
- // knows what to do with it. |
- StringBuilder cookieBuilder; |
- addCookieParam(cookieBuilder, cookie.name, cookie.value); |
- addCookieParam(cookieBuilder, "path", cookie.path); |
- if (cookie.expires) |
- addCookieParam(cookieBuilder, "expires", rfc2616DateStringFromTime(cookie.expires)); |
- if (cookie.httpOnly) |
- addCookieParam(cookieBuilder, "httpOnly", String()); |
- cookieBuilder.append(';'); |
- |
- String cookieURL; |
- if (!cookie.domain.isEmpty()) { |
- StringBuilder urlBuilder; |
- |
- urlBuilder.append(movieURL.protocol()); |
- urlBuilder.append("://"); |
- if (cookie.domain[0] == '.') |
- urlBuilder.append(cookie.domain.substring(1)); |
- else |
- urlBuilder.append(cookie.domain); |
- if (cookie.path.length() > 1) |
- urlBuilder.append(cookie.path); |
- |
- cookieURL = urlBuilder.toString(); |
- } else |
- cookieURL = movieURL; |
- |
- String string = cookieBuilder.toString(); |
- InternetSetCookieExW(cookieURL.charactersWithNullTermination(), 0, string.charactersWithNullTermination(), 0, 0); |
- } |
-} |
- |
-static void disableComponentsOnce() |
-{ |
- static bool sComponentsDisabled = false; |
- if (sComponentsDisabled) |
- return; |
- sComponentsDisabled = true; |
- |
- uint32_t componentsToDisable[][5] = { |
- {'eat ', 'TEXT', 'text', 0, 0}, |
- {'eat ', 'TXT ', 'text', 0, 0}, |
- {'eat ', 'utxt', 'text', 0, 0}, |
- {'eat ', 'TEXT', 'tx3g', 0, 0}, |
- }; |
- |
- for (size_t i = 0; i < WTF_ARRAY_LENGTH(componentsToDisable); ++i) |
- QTMovie::disableComponent(componentsToDisable[i]); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::resumeLoad() |
-{ |
- m_delayingLoad = false; |
- |
- if (!m_movieURL.isEmpty()) |
- loadInternal(m_movieURL); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::load(const String& url) |
-{ |
- m_movieURL = url; |
- |
- if (m_preload == MediaPlayer::None) { |
- m_delayingLoad = true; |
- return; |
- } |
- |
- loadInternal(url); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::loadInternal(const String& url) |
-{ |
- if (!QTMovie::initializeQuickTime()) { |
- // FIXME: is this the right error to return? |
- m_networkState = MediaPlayer::DecodeError; |
- m_player->networkStateChanged(); |
- return; |
- } |
- |
- disableComponentsOnce(); |
- |
- // Initialize the task timer. |
- MediaPlayerPrivateTaskTimer::initialize(); |
- |
- if (m_networkState != MediaPlayer::Loading) { |
- m_networkState = MediaPlayer::Loading; |
- m_player->networkStateChanged(); |
- } |
- if (m_readyState != MediaPlayer::HaveNothing) { |
- m_readyState = MediaPlayer::HaveNothing; |
- m_player->readyStateChanged(); |
- } |
- cancelSeek(); |
- |
- setUpCookiesForQuickTime(url); |
- |
- m_movie = adoptRef(new QTMovie(m_movieClient.get())); |
- |
- m_movie->load(url.characters(), url.length(), m_player->preservesPitch()); |
- m_movie->setVolume(m_player->volume()); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::prepareToPlay() |
-{ |
- if (!m_movie || m_delayingLoad) |
- resumeLoad(); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::play() |
-{ |
- if (!m_movie) |
- return; |
- m_startedPlaying = true; |
- |
- m_movie->play(); |
- m_visualContextTimer.startRepeating(1.0 / 30); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::pause() |
-{ |
- if (!m_movie) |
- return; |
- m_startedPlaying = false; |
- |
- m_movie->pause(); |
- m_visualContextTimer.stop(); |
-} |
- |
-float MediaPlayerPrivateQuickTimeVisualContext::duration() const |
-{ |
- if (!m_movie) |
- return 0; |
- return m_movie->duration(); |
-} |
- |
-float MediaPlayerPrivateQuickTimeVisualContext::currentTime() const |
-{ |
- if (!m_movie) |
- return 0; |
- return m_movie->currentTime(); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::seek(float time) |
-{ |
- cancelSeek(); |
- |
- if (!m_movie) |
- return; |
- |
- if (time > duration()) |
- time = duration(); |
- |
- m_seekTo = time; |
- if (maxTimeLoaded() >= m_seekTo) |
- doSeek(); |
- else |
- m_seekTimer.start(0, 0.5f); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::doSeek() |
-{ |
- float oldRate = m_movie->rate(); |
- if (oldRate) |
- m_movie->setRate(0); |
- m_movie->setCurrentTime(m_seekTo); |
- float timeAfterSeek = currentTime(); |
- // restore playback only if not at end, othewise QTMovie will loop |
- if (oldRate && timeAfterSeek < duration()) |
- m_movie->setRate(oldRate); |
- cancelSeek(); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::cancelSeek() |
-{ |
- m_seekTo = -1; |
- m_seekTimer.stop(); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::seekTimerFired(Timer<MediaPlayerPrivateQuickTimeVisualContext>*) |
-{ |
- if (!m_movie || !seeking() || currentTime() == m_seekTo) { |
- cancelSeek(); |
- updateStates(); |
- m_player->timeChanged(); |
- return; |
- } |
- |
- if (maxTimeLoaded() >= m_seekTo) |
- doSeek(); |
- else { |
- MediaPlayer::NetworkState state = networkState(); |
- if (state == MediaPlayer::Empty || state == MediaPlayer::Loaded) { |
- cancelSeek(); |
- updateStates(); |
- m_player->timeChanged(); |
- } |
- } |
-} |
- |
-bool MediaPlayerPrivateQuickTimeVisualContext::paused() const |
-{ |
- if (!m_movie) |
- return true; |
- return (!m_movie->rate()); |
-} |
- |
-bool MediaPlayerPrivateQuickTimeVisualContext::seeking() const |
-{ |
- if (!m_movie) |
- return false; |
- return m_seekTo >= 0; |
-} |
- |
-IntSize MediaPlayerPrivateQuickTimeVisualContext::naturalSize() const |
-{ |
- if (!m_movie) |
- return IntSize(); |
- int width; |
- int height; |
- m_movie->getNaturalSize(width, height); |
-#if USE(ACCELERATED_COMPOSITING) |
- CGSize originalSize = {width, height}; |
- CGSize transformedSize = CGSizeApplyAffineTransform(originalSize, m_movieTransform); |
- return IntSize(abs(transformedSize.width), abs(transformedSize.height)); |
-#else |
- return IntSize(width, height); |
-#endif |
-} |
- |
-bool MediaPlayerPrivateQuickTimeVisualContext::hasVideo() const |
-{ |
- if (!m_movie) |
- return false; |
- return m_movie->hasVideo(); |
-} |
- |
-bool MediaPlayerPrivateQuickTimeVisualContext::hasAudio() const |
-{ |
- if (!m_movie) |
- return false; |
- return m_movie->hasAudio(); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::setVolume(float volume) |
-{ |
- if (!m_movie) |
- return; |
- m_movie->setVolume(volume); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::setRate(float rate) |
-{ |
- if (!m_movie) |
- return; |
- |
- // Do not call setRate(...) unless we have started playing; otherwise |
- // QuickTime's VisualContext can get wedged waiting for a rate change |
- // call which will never come. |
- if (m_startedPlaying) |
- m_movie->setRate(rate); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::setPreservesPitch(bool preservesPitch) |
-{ |
- if (!m_movie) |
- return; |
- m_movie->setPreservesPitch(preservesPitch); |
-} |
- |
-bool MediaPlayerPrivateQuickTimeVisualContext::hasClosedCaptions() const |
-{ |
- if (!m_movie) |
- return false; |
- return m_movie->hasClosedCaptions(); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::setClosedCaptionsVisible(bool visible) |
-{ |
- if (!m_movie) |
- return; |
- m_movie->setClosedCaptionsVisible(visible); |
-} |
- |
-PassRefPtr<TimeRanges> MediaPlayerPrivateQuickTimeVisualContext::buffered() const |
-{ |
- RefPtr<TimeRanges> timeRanges = TimeRanges::create(); |
- float loaded = maxTimeLoaded(); |
- // rtsp streams are not buffered |
- if (!m_isStreaming && loaded > 0) |
- timeRanges->add(0, loaded); |
- return timeRanges.release(); |
-} |
- |
-float MediaPlayerPrivateQuickTimeVisualContext::maxTimeSeekable() const |
-{ |
- // infinite duration means live stream |
- return !std::isfinite(duration()) ? 0 : maxTimeLoaded(); |
-} |
- |
-float MediaPlayerPrivateQuickTimeVisualContext::maxTimeLoaded() const |
-{ |
- if (!m_movie) |
- return 0; |
- return m_movie->maxTimeLoaded(); |
-} |
- |
-bool MediaPlayerPrivateQuickTimeVisualContext::didLoadingProgress() const |
-{ |
- if (!m_movie || !duration()) |
- return false; |
- float currentMaxTimeLoaded = maxTimeLoaded(); |
- bool didLoadingProgress = currentMaxTimeLoaded != m_maxTimeLoadedAtLastDidLoadingProgress; |
- m_maxTimeLoadedAtLastDidLoadingProgress = currentMaxTimeLoaded; |
- return didLoadingProgress; |
-} |
- |
-unsigned MediaPlayerPrivateQuickTimeVisualContext::totalBytes() const |
-{ |
- if (!m_movie) |
- return 0; |
- return m_movie->dataSize(); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::cancelLoad() |
-{ |
- if (m_networkState < MediaPlayer::Loading || m_networkState == MediaPlayer::Loaded) |
- return; |
- |
- tearDownVideoRendering(); |
- |
- // Cancel the load by destroying the movie. |
- m_movie.clear(); |
- |
- updateStates(); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::updateStates() |
-{ |
- MediaPlayer::NetworkState oldNetworkState = m_networkState; |
- MediaPlayer::ReadyState oldReadyState = m_readyState; |
- |
- long loadState = m_movie ? m_movie->loadState() : QTMovieLoadStateError; |
- |
- if (loadState >= QTMovieLoadStateLoaded && m_readyState < MediaPlayer::HaveMetadata) { |
- m_movie->disableUnsupportedTracks(m_enabledTrackCount, m_totalTrackCount); |
- if (m_player->inMediaDocument()) { |
- if (!m_enabledTrackCount || m_enabledTrackCount != m_totalTrackCount) { |
- // This is a type of media that we do not handle directly with a <video> |
- // element, eg. QuickTime VR, a movie with a sprite track, etc. Tell the |
- // MediaPlayerClient that we won't support it. |
- sawUnsupportedTracks(); |
- return; |
- } |
- } else if (!m_enabledTrackCount) |
- loadState = QTMovieLoadStateError; |
- } |
- |
- // "Loaded" is reserved for fully buffered movies, never the case when streaming |
- if (loadState >= QTMovieLoadStateComplete && !m_isStreaming) { |
- m_networkState = MediaPlayer::Loaded; |
- m_readyState = MediaPlayer::HaveEnoughData; |
- } else if (loadState >= QTMovieLoadStatePlaythroughOK) { |
- m_readyState = MediaPlayer::HaveEnoughData; |
- } else if (loadState >= QTMovieLoadStatePlayable) { |
- // FIXME: This might not work correctly in streaming case, <rdar://problem/5693967> |
- m_readyState = currentTime() < maxTimeLoaded() ? MediaPlayer::HaveFutureData : MediaPlayer::HaveCurrentData; |
- } else if (loadState >= QTMovieLoadStateLoaded) { |
- m_readyState = MediaPlayer::HaveMetadata; |
- } else if (loadState > QTMovieLoadStateError) { |
- m_networkState = MediaPlayer::Loading; |
- m_readyState = MediaPlayer::HaveNothing; |
- } else { |
- if (m_player->inMediaDocument()) { |
- // Something went wrong in the loading of media within a standalone file. |
- // This can occur with chained ref movies that eventually resolve to a |
- // file we don't support. |
- sawUnsupportedTracks(); |
- return; |
- } |
- |
- float loaded = maxTimeLoaded(); |
- if (!loaded) |
- m_readyState = MediaPlayer::HaveNothing; |
- |
- if (!m_enabledTrackCount) |
- m_networkState = MediaPlayer::FormatError; |
- else { |
- // FIXME: We should differentiate between load/network errors and decode errors <rdar://problem/5605692> |
- if (loaded > 0) |
- m_networkState = MediaPlayer::DecodeError; |
- else |
- m_readyState = MediaPlayer::HaveNothing; |
- } |
- } |
- |
- if (isReadyForRendering() && !hasSetUpVideoRendering()) |
- setUpVideoRendering(); |
- |
- if (seeking()) |
- m_readyState = MediaPlayer::HaveNothing; |
- |
- if (m_networkState != oldNetworkState) |
- m_player->networkStateChanged(); |
- if (m_readyState != oldReadyState) |
- m_player->readyStateChanged(); |
-} |
- |
-bool MediaPlayerPrivateQuickTimeVisualContext::isReadyForRendering() const |
-{ |
- return m_readyState >= MediaPlayer::HaveMetadata && m_player->visible(); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::sawUnsupportedTracks() |
-{ |
- m_movie->setDisabled(true); |
- m_hasUnsupportedTracks = true; |
- m_player->mediaPlayerClient()->mediaPlayerSawUnsupportedTracks(m_player); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::didEnd() |
-{ |
- if (m_hasUnsupportedTracks) |
- return; |
- |
- m_startedPlaying = false; |
- |
- updateStates(); |
- m_player->timeChanged(); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::setSize(const IntSize& size) |
-{ |
- if (m_hasUnsupportedTracks || !m_movie || m_size == size) |
- return; |
- m_size = size; |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::setVisible(bool visible) |
-{ |
- if (m_hasUnsupportedTracks || !m_movie || m_visible == visible) |
- return; |
- |
- m_visible = visible; |
- if (m_visible) { |
- if (isReadyForRendering()) |
- setUpVideoRendering(); |
- } else |
- tearDownVideoRendering(); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::paint(GraphicsContext* p, const IntRect& r) |
-{ |
- MediaRenderingMode currentMode = currentRenderingMode(); |
- |
- if (currentMode == MediaRenderingNone) |
- return; |
- |
- if (currentMode == MediaRenderingSoftwareRenderer && !m_visualContext) |
- return; |
- |
- QTPixelBuffer buffer = m_visualContext->imageForTime(0); |
- if (buffer.pixelBufferRef()) { |
-#if USE(ACCELERATED_COMPOSITING) |
- if (m_qtVideoLayer) { |
- // We are probably being asked to render the video into a canvas, but |
- // there's a good chance the QTPixelBuffer is not ARGB and thus can't be |
- // drawn using CG. If so, fire up an ICMDecompressionSession and convert |
- // the current frame into something which can be rendered by CG. |
- if (!buffer.pixelFormatIs32ARGB() && !buffer.pixelFormatIs32BGRA()) { |
- // The decompression session will only decompress a specific pixelFormat |
- // at a specific width and height; if these differ, the session must be |
- // recreated with the new parameters. |
- if (!m_decompressionSession || !m_decompressionSession->canDecompress(buffer)) |
- m_decompressionSession = QTDecompressionSession::create(buffer.pixelFormatType(), buffer.width(), buffer.height()); |
- buffer = m_decompressionSession->decompress(buffer); |
- } |
- } |
-#endif |
- CGImageRef image = CreateCGImageFromPixelBuffer(buffer); |
- |
- CGContextRef context = p->platformContext(); |
- CGContextSaveGState(context); |
- CGContextTranslateCTM(context, r.x(), r.y()); |
- CGContextTranslateCTM(context, 0, r.height()); |
- CGContextScaleCTM(context, 1, -1); |
- CGContextDrawImage(context, CGRectMake(0, 0, r.width(), r.height()), image); |
- CGContextRestoreGState(context); |
- |
- CGImageRelease(image); |
- } |
- paintCompleted(*p, r); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::paintCompleted(GraphicsContext& context, const IntRect& rect) |
-{ |
- m_newFrameAvailable = false; |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::VisualContextClient::retrieveCurrentImageProc(void* refcon) |
-{ |
- static_cast<MediaPlayerPrivateQuickTimeVisualContext*>(refcon)->retrieveCurrentImage(); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::VisualContextClient::imageAvailableForTime(const QTCVTimeStamp* timeStamp) |
-{ |
- // This call may come in on another thread, so marshall to the main thread first: |
- callOnMainThread(&retrieveCurrentImageProc, m_parent); |
- |
- // callOnMainThread must be paired with cancelCallOnMainThread in the destructor, |
- // in case this object is deleted before the main thread request is handled. |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::visualContextTimerFired(Timer<MediaPlayerPrivateQuickTimeVisualContext>*) |
-{ |
- if (m_visualContext && m_visualContext->isImageAvailableForTime(0)) |
- retrieveCurrentImage(); |
-} |
- |
-static CFDictionaryRef QTCFDictionaryCreateWithDataCallback(CFAllocatorRef allocator, const UInt8* bytes, CFIndex length) |
-{ |
- RetainPtr<CFDataRef> data(AdoptCF, CFDataCreateWithBytesNoCopy(allocator, bytes, length, kCFAllocatorNull)); |
- if (!data) |
- return 0; |
- |
- return reinterpret_cast<CFDictionaryRef>(CFPropertyListCreateFromXMLData(allocator, data.get(), kCFPropertyListImmutable, 0)); |
-} |
- |
-static CGImageRef CreateCGImageFromPixelBuffer(QTPixelBuffer buffer) |
-{ |
-#if USE(ACCELERATED_COMPOSITING) |
- CGDataProviderRef provider = 0; |
- CGColorSpaceRef colorSpace = 0; |
- CGImageRef image = 0; |
- |
- size_t bitsPerComponent = 0; |
- size_t bitsPerPixel = 0; |
- CGImageAlphaInfo alphaInfo = kCGImageAlphaNone; |
- |
- if (buffer.pixelFormatIs32BGRA()) { |
- bitsPerComponent = 8; |
- bitsPerPixel = 32; |
- alphaInfo = (CGImageAlphaInfo)(kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little); |
- } else if (buffer.pixelFormatIs32ARGB()) { |
- bitsPerComponent = 8; |
- bitsPerPixel = 32; |
- alphaInfo = (CGImageAlphaInfo)(kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big); |
- } else { |
- // All other pixel formats are currently unsupported: |
- ASSERT_NOT_REACHED(); |
- } |
- |
- CGDataProviderDirectAccessCallbacks callbacks = { |
- &QTPixelBuffer::dataProviderGetBytePointerCallback, |
- &QTPixelBuffer::dataProviderReleaseBytePointerCallback, |
- &QTPixelBuffer::dataProviderGetBytesAtPositionCallback, |
- &QTPixelBuffer::dataProviderReleaseInfoCallback, |
- }; |
- |
- // Colorspace should be device, so that Quartz does not have to do an extra render. |
- colorSpace = CGColorSpaceCreateDeviceRGB(); |
- require(colorSpace, Bail); |
- |
- provider = CGDataProviderCreateDirectAccess(buffer.pixelBufferRef(), buffer.dataSize(), &callbacks); |
- require(provider, Bail); |
- |
- // CGDataProvider does not retain the buffer, but it will release it later, so do an extra retain here: |
- QTPixelBuffer::retainCallback(buffer.pixelBufferRef()); |
- |
- image = CGImageCreate(buffer.width(), buffer.height(), bitsPerComponent, bitsPerPixel, buffer.bytesPerRow(), colorSpace, alphaInfo, provider, 0, false, kCGRenderingIntentDefault); |
- |
-Bail: |
- // Once the image is created we can release our reference to the provider and the colorspace, they are retained by the image |
- if (provider) |
- CGDataProviderRelease(provider); |
- if (colorSpace) |
- CGColorSpaceRelease(colorSpace); |
- |
- return image; |
-#else |
- return 0; |
-#endif |
-} |
- |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::retrieveCurrentImage() |
-{ |
- if (!m_visualContext) |
- return; |
- |
-#if USE(ACCELERATED_COMPOSITING) |
- if (m_qtVideoLayer) { |
- |
- QTPixelBuffer buffer = m_visualContext->imageForTime(0); |
- if (!buffer.pixelBufferRef()) |
- return; |
- |
- PlatformCALayer* layer = m_qtVideoLayer.get(); |
- |
- if (!buffer.lockBaseAddress()) { |
- if (requiredDllsAvailable()) { |
- if (!m_imageQueue) { |
- m_imageQueue = adoptPtr(new WKCAImageQueue(buffer.width(), buffer.height(), 30)); |
- m_imageQueue->setFlags(WKCAImageQueue::Fill, WKCAImageQueue::Fill); |
- layer->setContents(m_imageQueue->get()); |
- } |
- |
- // Debug QuickTime links against a non-Debug version of CoreFoundation, so the |
- // CFDictionary attached to the CVPixelBuffer cannot be directly passed on into the |
- // CAImageQueue without being converted to a non-Debug CFDictionary. Additionally, |
- // old versions of QuickTime used a non-AAS CoreFoundation, so the types are not |
- // interchangable even in the release case. |
- RetainPtr<CFDictionaryRef> attachments(AdoptCF, QTCFDictionaryCreateCopyWithDataCallback(kCFAllocatorDefault, buffer.attachments(), &QTCFDictionaryCreateWithDataCallback)); |
- CFTimeInterval imageTime = QTMovieVisualContext::currentHostTime(); |
- |
- m_imageQueue->collect(); |
- |
- uint64_t imageId = m_imageQueue->registerPixelBuffer(buffer.baseAddress(), buffer.dataSize(), buffer.bytesPerRow(), buffer.width(), buffer.height(), buffer.pixelFormatType(), attachments.get(), 0); |
- |
- if (m_imageQueue->insertImage(imageTime, WKCAImageQueue::Buffer, imageId, WKCAImageQueue::Opaque | WKCAImageQueue::Flush, &QTPixelBuffer::imageQueueReleaseCallback, buffer.pixelBufferRef())) { |
- // Retain the buffer one extra time so it doesn't dissappear before CAImageQueue decides to release it: |
- QTPixelBuffer::retainCallback(buffer.pixelBufferRef()); |
- } |
- |
- } else { |
- CGImageRef image = CreateCGImageFromPixelBuffer(buffer); |
- layer->setContents(image); |
- CGImageRelease(image); |
- } |
- |
- buffer.unlockBaseAddress(); |
- layer->setNeedsCommit(); |
- } |
- } else |
-#endif |
- m_player->repaint(); |
- |
- m_visualContext->task(); |
-} |
- |
-static HashSet<String> mimeTypeCache() |
-{ |
- DEFINE_STATIC_LOCAL(HashSet<String>, typeCache, ()); |
- static bool typeListInitialized = false; |
- |
- if (!typeListInitialized) { |
- unsigned count = QTMovie::countSupportedTypes(); |
- for (unsigned n = 0; n < count; n++) { |
- const UChar* character; |
- unsigned len; |
- QTMovie::getSupportedType(n, character, len); |
- if (len) |
- typeCache.add(String(character, len)); |
- } |
- |
- typeListInitialized = true; |
- } |
- |
- return typeCache; |
-} |
- |
-static CFStringRef createVersionStringFromModuleName(LPCWSTR moduleName) |
-{ |
- HMODULE module = GetModuleHandleW(moduleName); |
- if (!module) |
- return 0; |
- |
- wchar_t filePath[MAX_PATH] = {0}; |
- if (!GetModuleFileNameW(module, filePath, MAX_PATH)) |
- return 0; |
- |
- DWORD versionInfoSize = GetFileVersionInfoSizeW(filePath, 0); |
- if (!versionInfoSize) |
- return 0; |
- |
- CFStringRef versionString = 0; |
- void* versionInfo = calloc(versionInfoSize, sizeof(char)); |
- if (GetFileVersionInfo(filePath, 0, versionInfoSize, versionInfo)) { |
- VS_FIXEDFILEINFO* fileInfo = 0; |
- UINT fileInfoLength = 0; |
- |
- if (VerQueryValueW(versionInfo, L"\\", reinterpret_cast<LPVOID*>(&fileInfo), &fileInfoLength)) { |
- versionString = CFStringCreateWithFormat(kCFAllocatorDefault, 0, CFSTR("%d.%d.%d.%d"), |
- HIWORD(fileInfo->dwFileVersionMS), LOWORD(fileInfo->dwFileVersionMS), |
- HIWORD(fileInfo->dwFileVersionLS), LOWORD(fileInfo->dwFileVersionLS)); |
- } |
- } |
- free(versionInfo); |
- |
- return versionString; |
-} |
- |
-static bool requiredDllsAvailable() |
-{ |
- static bool s_prerequisitesChecked = false; |
- static bool s_prerequisitesSatisfied; |
- static const CFStringRef kMinQuartzCoreVersion = CFSTR("1.0.42.0"); |
- static const CFStringRef kMinCoreVideoVersion = CFSTR("1.0.1.0"); |
- |
- if (s_prerequisitesChecked) |
- return s_prerequisitesSatisfied; |
- s_prerequisitesChecked = true; |
- s_prerequisitesSatisfied = false; |
- |
- CFStringRef quartzCoreString = createVersionStringFromModuleName(L"QuartzCore"); |
- if (!quartzCoreString) |
- quartzCoreString = createVersionStringFromModuleName(L"QuartzCore_debug"); |
- |
- CFStringRef coreVideoString = createVersionStringFromModuleName(L"CoreVideo"); |
- if (!coreVideoString) |
- coreVideoString = createVersionStringFromModuleName(L"CoreVideo_debug"); |
- |
- s_prerequisitesSatisfied = (quartzCoreString && coreVideoString |
- && CFStringCompare(quartzCoreString, kMinQuartzCoreVersion, kCFCompareNumerically) != kCFCompareLessThan |
- && CFStringCompare(coreVideoString, kMinCoreVideoVersion, kCFCompareNumerically) != kCFCompareLessThan); |
- |
- if (quartzCoreString) |
- CFRelease(quartzCoreString); |
- if (coreVideoString) |
- CFRelease(coreVideoString); |
- |
- return s_prerequisitesSatisfied; |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::getSupportedTypes(HashSet<String>& types) |
-{ |
- types = mimeTypeCache(); |
-} |
- |
-bool MediaPlayerPrivateQuickTimeVisualContext::isAvailable() |
-{ |
- return QTMovie::initializeQuickTime(); |
-} |
- |
-MediaPlayer::SupportsType MediaPlayerPrivateQuickTimeVisualContext::supportsType(const String& type, const String& codecs, const KURL&) |
-{ |
- // only return "IsSupported" if there is no codecs parameter for now as there is no way to ask QT if it supports an |
- // extended MIME type |
- return mimeTypeCache().contains(type) ? (codecs.isEmpty() ? MediaPlayer::MayBeSupported : MediaPlayer::IsSupported) : MediaPlayer::IsNotSupported; |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::MovieClient::movieEnded(QTMovie* movie) |
-{ |
- if (m_parent->m_hasUnsupportedTracks) |
- return; |
- |
- m_parent->m_visualContextTimer.stop(); |
- |
- ASSERT(m_parent->m_movie.get() == movie); |
- m_parent->didEnd(); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::MovieClient::movieLoadStateChanged(QTMovie* movie) |
-{ |
- if (m_parent->m_hasUnsupportedTracks) |
- return; |
- |
- ASSERT(m_parent->m_movie.get() == movie); |
- m_parent->updateStates(); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::MovieClient::movieTimeChanged(QTMovie* movie) |
-{ |
- if (m_parent->m_hasUnsupportedTracks) |
- return; |
- |
- ASSERT(m_parent->m_movie.get() == movie); |
- m_parent->updateStates(); |
- m_parent->m_player->timeChanged(); |
-} |
- |
-bool MediaPlayerPrivateQuickTimeVisualContext::hasSingleSecurityOrigin() const |
-{ |
- // We tell quicktime to disallow resources that come from different origins |
- // so we all media is single origin. |
- return true; |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::setPreload(MediaPlayer::Preload preload) |
-{ |
- m_preload = preload; |
- if (m_delayingLoad && m_preload != MediaPlayer::None) |
- resumeLoad(); |
-} |
- |
-float MediaPlayerPrivateQuickTimeVisualContext::mediaTimeForTimeValue(float timeValue) const |
-{ |
- long timeScale; |
- if (m_readyState < MediaPlayer::HaveMetadata || !(timeScale = m_movie->timeScale())) |
- return timeValue; |
- |
- long mediaTimeValue = lroundf(timeValue * timeScale); |
- return static_cast<float>(mediaTimeValue) / timeScale; |
-} |
- |
-MediaPlayerPrivateQuickTimeVisualContext::MediaRenderingMode MediaPlayerPrivateQuickTimeVisualContext::currentRenderingMode() const |
-{ |
- if (!m_movie) |
- return MediaRenderingNone; |
- |
-#if USE(ACCELERATED_COMPOSITING) |
- if (m_qtVideoLayer) |
- return MediaRenderingMovieLayer; |
-#endif |
- |
- return m_visualContext ? MediaRenderingSoftwareRenderer : MediaRenderingNone; |
-} |
- |
-MediaPlayerPrivateQuickTimeVisualContext::MediaRenderingMode MediaPlayerPrivateQuickTimeVisualContext::preferredRenderingMode() const |
-{ |
- if (!m_player->frameView() || !m_movie) |
- return MediaRenderingNone; |
- |
-#if USE(ACCELERATED_COMPOSITING) |
- if (supportsAcceleratedRendering() && m_player->mediaPlayerClient()->mediaPlayerRenderingCanBeAccelerated(m_player)) |
- return MediaRenderingMovieLayer; |
-#endif |
- |
- return MediaRenderingSoftwareRenderer; |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::setUpVideoRendering() |
-{ |
- MediaRenderingMode currentMode = currentRenderingMode(); |
- MediaRenderingMode preferredMode = preferredRenderingMode(); |
- |
-#if !USE(ACCELERATED_COMPOSITING) |
- ASSERT(preferredMode != MediaRenderingMovieLayer); |
-#endif |
- |
- if (currentMode == preferredMode && currentMode != MediaRenderingNone) |
- return; |
- |
- if (currentMode != MediaRenderingNone) |
- tearDownVideoRendering(); |
- |
- if (preferredMode == MediaRenderingMovieLayer) |
- createLayerForMovie(); |
- |
-#if USE(ACCELERATED_COMPOSITING) |
- if (currentMode == MediaRenderingMovieLayer || preferredMode == MediaRenderingMovieLayer) |
- m_player->mediaPlayerClient()->mediaPlayerRenderingModeChanged(m_player); |
-#endif |
- |
- QTPixelBuffer::Type contextType = requiredDllsAvailable() && preferredMode == MediaRenderingMovieLayer ? QTPixelBuffer::ConfigureForCAImageQueue : QTPixelBuffer::ConfigureForCGImage; |
- m_visualContext = QTMovieVisualContext::create(m_visualContextClient.get(), contextType); |
- m_visualContext->setMovie(m_movie.get()); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::tearDownVideoRendering() |
-{ |
-#if USE(ACCELERATED_COMPOSITING) |
- if (m_qtVideoLayer) |
- destroyLayerForMovie(); |
-#endif |
- |
- m_visualContext = 0; |
-} |
- |
-bool MediaPlayerPrivateQuickTimeVisualContext::hasSetUpVideoRendering() const |
-{ |
-#if USE(ACCELERATED_COMPOSITING) |
- return m_qtVideoLayer || (currentRenderingMode() != MediaRenderingMovieLayer && m_visualContext); |
-#else |
- return true; |
-#endif |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::retrieveAndResetMovieTransform() |
-{ |
-#if USE(ACCELERATED_COMPOSITING) |
- // First things first, reset the total movie transform so that |
- // we can bail out early: |
- m_movieTransform = CGAffineTransformIdentity; |
- |
- if (!m_movie || !m_movie->hasVideo()) |
- return; |
- |
- // This trick will only work on movies with a single video track, |
- // so bail out early if the video contains more than one (or zero) |
- // video tracks. |
- QTTrackArray videoTracks = m_movie->videoTracks(); |
- if (videoTracks.size() != 1) |
- return; |
- |
- QTTrack* track = videoTracks[0].get(); |
- ASSERT(track); |
- |
- CGAffineTransform movieTransform = m_movie->getTransform(); |
- if (!CGAffineTransformEqualToTransform(movieTransform, CGAffineTransformIdentity)) |
- m_movie->resetTransform(); |
- |
- CGAffineTransform trackTransform = track->getTransform(); |
- if (!CGAffineTransformEqualToTransform(trackTransform, CGAffineTransformIdentity)) |
- track->resetTransform(); |
- |
- // Multiply the two transforms together, taking care to |
- // do so in the correct order, track * movie = final: |
- m_movieTransform = CGAffineTransformConcat(trackTransform, movieTransform); |
-#endif |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::createLayerForMovie() |
-{ |
-#if USE(ACCELERATED_COMPOSITING) |
- ASSERT(supportsAcceleratedRendering()); |
- |
- if (!m_movie || m_qtVideoLayer) |
- return; |
- |
- // Create a PlatformCALayer which will transform the contents of the video layer |
- // which is in m_qtVideoLayer. |
- m_transformLayer = PlatformCALayer::create(PlatformCALayer::LayerTypeLayer, m_layerClient.get()); |
- if (!m_transformLayer) |
- return; |
- |
- // Mark the layer as anchored in the top left. |
- m_transformLayer->setAnchorPoint(FloatPoint3D()); |
- |
- m_qtVideoLayer = PlatformCALayer::create(PlatformCALayer::LayerTypeLayer, 0); |
- if (!m_qtVideoLayer) |
- return; |
- |
- if (CGAffineTransformEqualToTransform(m_movieTransform, CGAffineTransformIdentity)) |
- retrieveAndResetMovieTransform(); |
- CGAffineTransform t = m_movieTransform; |
- |
- // Remove the translation portion of the transform, since we will always rotate about |
- // the layer's center point. In our limited use-case (a single video track), this is |
- // safe: |
- t.tx = t.ty = 0; |
- m_qtVideoLayer->setTransform(CATransform3DMakeAffineTransform(t)); |
- |
-#ifndef NDEBUG |
- m_qtVideoLayer->setName("Video layer"); |
-#endif |
- m_transformLayer->appendSublayer(m_qtVideoLayer.get()); |
- m_transformLayer->setNeedsLayout(); |
- // The layer will get hooked up via RenderLayerBacking::updateGraphicsLayerConfiguration(). |
-#endif |
- |
- // Fill the newly created layer with image data, so we're not looking at |
- // an empty layer until the next time a new image is available, which could |
- // be a long time if we're paused. |
- if (m_visualContext) |
- retrieveCurrentImage(); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::destroyLayerForMovie() |
-{ |
-#if USE(ACCELERATED_COMPOSITING) |
- if (m_qtVideoLayer) { |
- m_qtVideoLayer->removeFromSuperlayer(); |
- m_qtVideoLayer = 0; |
- } |
- |
- if (m_transformLayer) |
- m_transformLayer = 0; |
- |
- if (m_imageQueue) |
- m_imageQueue = nullptr; |
-#endif |
-} |
- |
-#if USE(ACCELERATED_COMPOSITING) |
-bool MediaPlayerPrivateQuickTimeVisualContext::supportsAcceleratedRendering() const |
-{ |
- return isReadyForRendering(); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::acceleratedRenderingStateChanged() |
-{ |
- // Set up or change the rendering path if necessary. |
- setUpVideoRendering(); |
-} |
- |
-void MediaPlayerPrivateQuickTimeVisualContext::setPrivateBrowsingMode(bool privateBrowsing) |
-{ |
- m_privateBrowsing = privateBrowsing; |
- if (m_movie) |
- m_movie->setPrivateBrowsingMode(m_privateBrowsing); |
-} |
- |
-#endif |
- |
- |
-} |
- |
-#endif |