| Index: Source/WebCore/platform/graphics/win/QTMovie.cpp
|
| diff --git a/Source/WebCore/platform/graphics/win/QTMovie.cpp b/Source/WebCore/platform/graphics/win/QTMovie.cpp
|
| deleted file mode 100644
|
| index 7ce28e5156dfccb9c804e33ef9fc48b357f41fae..0000000000000000000000000000000000000000
|
| --- a/Source/WebCore/platform/graphics/win/QTMovie.cpp
|
| +++ /dev/null
|
| @@ -1,924 +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"
|
| -
|
| -#include "QTMovie.h"
|
| -
|
| -#include "QTMovieTask.h"
|
| -#include "QTMovieWinTimer.h"
|
| -#include <FixMath.h>
|
| -#include <GXMath.h>
|
| -#include <Movies.h>
|
| -#include <QTML.h>
|
| -#include <QuickTimeComponents.h>
|
| -#include <WebKitSystemInterface/WebKitSystemInterface.h>
|
| -#include <wtf/Assertions.h>
|
| -#include <wtf/MathExtras.h>
|
| -#include <wtf/Noncopyable.h>
|
| -#include <wtf/Vector.h>
|
| -
|
| -using namespace std;
|
| -
|
| -static const long minimumQuickTimeVersion = 0x07300000; // 7.3
|
| -
|
| -static const long closedCaptionTrackType = 'clcp';
|
| -static const long subTitleTrackType = 'sbtl';
|
| -static const long mpeg4ObjectDescriptionTrackType = 'odsm';
|
| -static const long mpeg4SceneDescriptionTrackType = 'sdsm';
|
| -static const long closedCaptionDisplayPropertyID = 'disp';
|
| -
|
| -// Resizing GWorlds is slow, give them a minimum size so size of small
|
| -// videos can be animated smoothly
|
| -static const int cGWorldMinWidth = 640;
|
| -static const int cGWorldMinHeight = 360;
|
| -
|
| -static const float cNonContinuousTimeChange = 0.2f;
|
| -
|
| -union UppParam {
|
| - long longValue;
|
| - void* ptr;
|
| -};
|
| -
|
| -static CFMutableArrayRef gSupportedTypes = 0;
|
| -static SInt32 quickTimeVersion = 0;
|
| -
|
| -class QTMoviePrivate : public QTMovieTaskClient {
|
| - WTF_MAKE_NONCOPYABLE(QTMoviePrivate);
|
| -public:
|
| - QTMoviePrivate();
|
| - ~QTMoviePrivate();
|
| - void task();
|
| - void startTask();
|
| - void endTask();
|
| -
|
| - void createMovieController();
|
| - void cacheMovieScale();
|
| -
|
| - QTMovie* m_movieWin;
|
| - Movie m_movie;
|
| - MovieController m_movieController;
|
| - bool m_tasking;
|
| - bool m_disabled;
|
| - Vector<QTMovieClient*> m_clients;
|
| - long m_loadState;
|
| - bool m_ended;
|
| - bool m_seeking;
|
| - float m_lastMediaTime;
|
| - double m_lastLoadStateCheckTime;
|
| - int m_width;
|
| - int m_height;
|
| - bool m_visible;
|
| - long m_loadError;
|
| - float m_widthScaleFactor;
|
| - float m_heightScaleFactor;
|
| - CFURLRef m_currentURL;
|
| - float m_timeToRestore;
|
| - float m_rateToRestore;
|
| - bool m_privateBrowsing;
|
| -#if !ASSERT_DISABLED
|
| - bool m_scaleCached;
|
| -#endif
|
| -};
|
| -
|
| -QTMoviePrivate::QTMoviePrivate()
|
| - : m_movieWin(0)
|
| - , m_movie(0)
|
| - , m_movieController(0)
|
| - , m_tasking(false)
|
| - , m_loadState(0)
|
| - , m_ended(false)
|
| - , m_seeking(false)
|
| - , m_lastMediaTime(0)
|
| - , m_lastLoadStateCheckTime(0)
|
| - , m_width(0)
|
| - , m_height(0)
|
| - , m_visible(false)
|
| - , m_loadError(0)
|
| - , m_widthScaleFactor(1)
|
| - , m_heightScaleFactor(1)
|
| - , m_currentURL(0)
|
| - , m_timeToRestore(-1.0f)
|
| - , m_rateToRestore(-1.0f)
|
| - , m_disabled(false)
|
| - , m_privateBrowsing(false)
|
| -#if !ASSERT_DISABLED
|
| - , m_scaleCached(false)
|
| -#endif
|
| -{
|
| -}
|
| -
|
| -QTMoviePrivate::~QTMoviePrivate()
|
| -{
|
| - endTask();
|
| - if (m_movieController)
|
| - DisposeMovieController(m_movieController);
|
| - if (m_movie)
|
| - DisposeMovie(m_movie);
|
| - if (m_currentURL)
|
| - CFRelease(m_currentURL);
|
| -}
|
| -
|
| -void QTMoviePrivate::startTask()
|
| -{
|
| - if (!m_tasking) {
|
| - QTMovieTask::sharedTask()->addTaskClient(this);
|
| - m_tasking = true;
|
| - }
|
| - QTMovieTask::sharedTask()->updateTaskTimer();
|
| -}
|
| -
|
| -void QTMoviePrivate::endTask()
|
| -{
|
| - if (m_tasking) {
|
| - QTMovieTask::sharedTask()->removeTaskClient(this);
|
| - m_tasking = false;
|
| - }
|
| - QTMovieTask::sharedTask()->updateTaskTimer();
|
| -}
|
| -
|
| -void QTMoviePrivate::task()
|
| -{
|
| - ASSERT(m_tasking);
|
| -
|
| - if (!m_loadError) {
|
| - if (m_movieController)
|
| - MCIdle(m_movieController);
|
| - else
|
| - MoviesTask(m_movie, 0);
|
| - }
|
| -
|
| - // GetMovieLoadState documentation says that you should not call it more often than every quarter of a second.
|
| - if (systemTime() >= m_lastLoadStateCheckTime + 0.25 || m_loadError) {
|
| - // If load fails QT's load state is QTMovieLoadStateComplete.
|
| - // This is different from QTKit API and seems strange.
|
| - long loadState = m_loadError ? QTMovieLoadStateError : GetMovieLoadState(m_movie);
|
| - if (loadState != m_loadState) {
|
| - // we only need to erase the movie gworld when the load state changes to loaded while it
|
| - // is visible as the gworld is destroyed/created when visibility changes
|
| - bool shouldRestorePlaybackState = false;
|
| - bool movieNewlyPlayable = loadState >= QTMovieLoadStateLoaded && m_loadState < QTMovieLoadStateLoaded;
|
| - m_loadState = loadState;
|
| - if (movieNewlyPlayable) {
|
| - cacheMovieScale();
|
| - shouldRestorePlaybackState = true;
|
| - }
|
| -
|
| - if (!m_movieController && m_loadState >= QTMovieLoadStateLoaded)
|
| - createMovieController();
|
| -
|
| - for (size_t i = 0; i < m_clients.size(); ++i)
|
| - m_clients[i]->movieLoadStateChanged(m_movieWin);
|
| -
|
| - if (shouldRestorePlaybackState && m_timeToRestore != -1.0f) {
|
| - m_movieWin->setCurrentTime(m_timeToRestore);
|
| - m_timeToRestore = -1.0f;
|
| - m_movieWin->setRate(m_rateToRestore);
|
| - m_rateToRestore = -1.0f;
|
| - }
|
| -
|
| - if (m_disabled) {
|
| - endTask();
|
| - return;
|
| - }
|
| - }
|
| - m_lastLoadStateCheckTime = systemTime();
|
| - }
|
| -
|
| - bool ended = !!IsMovieDone(m_movie);
|
| - if (ended != m_ended) {
|
| - m_ended = ended;
|
| - if (ended) {
|
| - for (size_t i = 0; i < m_clients.size(); ++i)
|
| - m_clients[i]->movieEnded(m_movieWin);
|
| - }
|
| - }
|
| -
|
| - float time = m_movieWin->currentTime();
|
| - if (time < m_lastMediaTime || time >= m_lastMediaTime + cNonContinuousTimeChange || m_seeking) {
|
| - m_seeking = false;
|
| - for (size_t i = 0; i < m_clients.size(); ++i)
|
| - m_clients[i]->movieTimeChanged(m_movieWin);
|
| - }
|
| - m_lastMediaTime = time;
|
| -
|
| - if (m_loadError)
|
| - endTask();
|
| - else
|
| - QTMovieTask::sharedTask()->updateTaskTimer();
|
| -}
|
| -
|
| -void QTMoviePrivate::createMovieController()
|
| -{
|
| - Rect bounds;
|
| - long flags;
|
| -
|
| - if (!m_movie)
|
| - return;
|
| -
|
| - if (m_movieController)
|
| - DisposeMovieController(m_movieController);
|
| -
|
| - GetMovieBox(m_movie, &bounds);
|
| - flags = mcTopLeftMovie | mcNotVisible;
|
| - m_movieController = NewMovieController(m_movie, &bounds, flags);
|
| - if (!m_movieController)
|
| - return;
|
| -
|
| - // Disable automatic looping.
|
| - MCDoAction(m_movieController, mcActionSetLooping, 0);
|
| -}
|
| -
|
| -void QTMoviePrivate::cacheMovieScale()
|
| -{
|
| - Rect naturalRect;
|
| - Rect initialRect;
|
| -
|
| - GetMovieNaturalBoundsRect(m_movie, &naturalRect);
|
| - GetMovieBox(m_movie, &initialRect);
|
| -
|
| - float naturalWidth = naturalRect.right - naturalRect.left;
|
| - float naturalHeight = naturalRect.bottom - naturalRect.top;
|
| -
|
| - if (naturalWidth)
|
| - m_widthScaleFactor = (initialRect.right - initialRect.left) / naturalWidth;
|
| - if (naturalHeight)
|
| - m_heightScaleFactor = (initialRect.bottom - initialRect.top) / naturalHeight;
|
| -#if !ASSERT_DISABLED
|
| - m_scaleCached = true;
|
| -#endif
|
| -}
|
| -
|
| -QTMovie::QTMovie(QTMovieClient* client)
|
| - : m_private(new QTMoviePrivate())
|
| -{
|
| - m_private->m_movieWin = this;
|
| - if (client)
|
| - m_private->m_clients.append(client);
|
| - initializeQuickTime();
|
| -}
|
| -
|
| -QTMovie::~QTMovie()
|
| -{
|
| - delete m_private;
|
| -}
|
| -
|
| -void QTMovie::disableComponent(uint32_t cd[5])
|
| -{
|
| - ComponentDescription nullDesc = {'null', 'base', kAppleManufacturer, 0, 0};
|
| - Component nullComp = FindNextComponent(0, &nullDesc);
|
| - Component disabledComp = 0;
|
| -
|
| - while (disabledComp = FindNextComponent(disabledComp, (ComponentDescription*)&cd[0]))
|
| - CaptureComponent(disabledComp, nullComp);
|
| -}
|
| -
|
| -void QTMovie::addClient(QTMovieClient* client)
|
| -{
|
| - if (client)
|
| - m_private->m_clients.append(client);
|
| -}
|
| -
|
| -void QTMovie::removeClient(QTMovieClient* client)
|
| -{
|
| - size_t indexOfClient = m_private->m_clients.find(client);
|
| - if (indexOfClient != notFound)
|
| - m_private->m_clients.remove(indexOfClient);
|
| -}
|
| -
|
| -void QTMovie::play()
|
| -{
|
| - m_private->m_timeToRestore = -1.0f;
|
| -
|
| - if (m_private->m_movieController)
|
| - MCDoAction(m_private->m_movieController, mcActionPrerollAndPlay, (void *)GetMoviePreferredRate(m_private->m_movie));
|
| - else
|
| - StartMovie(m_private->m_movie);
|
| - m_private->startTask();
|
| -}
|
| -
|
| -void QTMovie::pause()
|
| -{
|
| - m_private->m_timeToRestore = -1.0f;
|
| -
|
| - if (m_private->m_movieController)
|
| - MCDoAction(m_private->m_movieController, mcActionPlay, 0);
|
| - else
|
| - StopMovie(m_private->m_movie);
|
| - QTMovieTask::sharedTask()->updateTaskTimer();
|
| -}
|
| -
|
| -float QTMovie::rate() const
|
| -{
|
| - if (!m_private->m_movie)
|
| - return 0;
|
| - return FixedToFloat(GetMovieRate(m_private->m_movie));
|
| -}
|
| -
|
| -void QTMovie::setRate(float rate)
|
| -{
|
| - if (!m_private->m_movie)
|
| - return;
|
| - m_private->m_timeToRestore = -1.0f;
|
| -
|
| - if (m_private->m_movieController)
|
| - MCDoAction(m_private->m_movieController, mcActionPrerollAndPlay, (void *)FloatToFixed(rate));
|
| - else
|
| - SetMovieRate(m_private->m_movie, FloatToFixed(rate));
|
| - QTMovieTask::sharedTask()->updateTaskTimer();
|
| -}
|
| -
|
| -float QTMovie::duration() const
|
| -{
|
| - if (!m_private->m_movie)
|
| - return 0;
|
| - TimeValue val = GetMovieDuration(m_private->m_movie);
|
| - TimeScale scale = GetMovieTimeScale(m_private->m_movie);
|
| - return static_cast<float>(val) / scale;
|
| -}
|
| -
|
| -float QTMovie::currentTime() const
|
| -{
|
| - if (!m_private->m_movie)
|
| - return 0;
|
| - TimeValue val = GetMovieTime(m_private->m_movie, 0);
|
| - TimeScale scale = GetMovieTimeScale(m_private->m_movie);
|
| - return static_cast<float>(val) / scale;
|
| -}
|
| -
|
| -void QTMovie::setCurrentTime(float time) const
|
| -{
|
| - if (!m_private->m_movie)
|
| - return;
|
| -
|
| - m_private->m_timeToRestore = -1.0f;
|
| -
|
| - m_private->m_seeking = true;
|
| - TimeScale scale = GetMovieTimeScale(m_private->m_movie);
|
| - if (m_private->m_movieController) {
|
| - QTRestartAtTimeRecord restart = { lroundf(time * scale) , 0 };
|
| - MCDoAction(m_private->m_movieController, mcActionRestartAtTime, (void *)&restart);
|
| - } else
|
| - SetMovieTimeValue(m_private->m_movie, TimeValue(lroundf(time * scale)));
|
| - QTMovieTask::sharedTask()->updateTaskTimer();
|
| -}
|
| -
|
| -void QTMovie::setVolume(float volume)
|
| -{
|
| - if (!m_private->m_movie)
|
| - return;
|
| - SetMovieVolume(m_private->m_movie, static_cast<short>(volume * 256));
|
| -}
|
| -
|
| -void QTMovie::setPreservesPitch(bool preservesPitch)
|
| -{
|
| - if (!m_private->m_movie || !m_private->m_currentURL)
|
| - return;
|
| -
|
| - OSErr error;
|
| - bool prop = false;
|
| -
|
| - error = QTGetMovieProperty(m_private->m_movie, kQTPropertyClass_Audio, kQTAudioPropertyID_RateChangesPreservePitch,
|
| - sizeof(kQTAudioPropertyID_RateChangesPreservePitch), static_cast<QTPropertyValuePtr>(&prop), 0);
|
| -
|
| - if (error || prop == preservesPitch)
|
| - return;
|
| -
|
| - m_private->m_timeToRestore = currentTime();
|
| - m_private->m_rateToRestore = rate();
|
| - load(m_private->m_currentURL, preservesPitch);
|
| -}
|
| -
|
| -unsigned QTMovie::dataSize() const
|
| -{
|
| - if (!m_private->m_movie)
|
| - return 0;
|
| - return GetMovieDataSize(m_private->m_movie, 0, GetMovieDuration(m_private->m_movie));
|
| -}
|
| -
|
| -float QTMovie::maxTimeLoaded() const
|
| -{
|
| - if (!m_private->m_movie)
|
| - return 0;
|
| - TimeValue val;
|
| - GetMaxLoadedTimeInMovie(m_private->m_movie, &val);
|
| - TimeScale scale = GetMovieTimeScale(m_private->m_movie);
|
| - return static_cast<float>(val) / scale;
|
| -}
|
| -
|
| -long QTMovie::loadState() const
|
| -{
|
| - return m_private->m_loadState;
|
| -}
|
| -
|
| -void QTMovie::getNaturalSize(int& width, int& height)
|
| -{
|
| - Rect rect = { 0, };
|
| -
|
| - if (m_private->m_movie)
|
| - GetMovieNaturalBoundsRect(m_private->m_movie, &rect);
|
| - width = (rect.right - rect.left) * m_private->m_widthScaleFactor;
|
| - height = (rect.bottom - rect.top) * m_private->m_heightScaleFactor;
|
| -}
|
| -
|
| -void QTMovie::loadPath(const UChar* url, int len, bool preservesPitch)
|
| -{
|
| - CFStringRef urlStringRef = CFStringCreateWithCharacters(kCFAllocatorDefault, reinterpret_cast<const UniChar*>(url), len);
|
| - CFURLRef cfURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, urlStringRef, kCFURLWindowsPathStyle, false);
|
| -
|
| - load(cfURL, preservesPitch);
|
| -
|
| - if (cfURL)
|
| - CFRelease(cfURL);
|
| - if (urlStringRef)
|
| - CFRelease(urlStringRef);
|
| -}
|
| -
|
| -void QTMovie::load(const UChar* url, int len, bool preservesPitch)
|
| -{
|
| - CFStringRef urlStringRef = CFStringCreateWithCharacters(kCFAllocatorDefault, reinterpret_cast<const UniChar*>(url), len);
|
| - CFURLRef cfURL = CFURLCreateWithString(kCFAllocatorDefault, urlStringRef, 0);
|
| -
|
| - load(cfURL, preservesPitch);
|
| -
|
| - if (cfURL)
|
| - CFRelease(cfURL);
|
| - if (urlStringRef)
|
| - CFRelease(urlStringRef);
|
| -}
|
| -
|
| -void QTMovie::load(CFURLRef url, bool preservesPitch)
|
| -{
|
| - if (!url)
|
| - return;
|
| -
|
| - if (m_private->m_movie) {
|
| - m_private->endTask();
|
| - if (m_private->m_movieController)
|
| - DisposeMovieController(m_private->m_movieController);
|
| - m_private->m_movieController = 0;
|
| - DisposeMovie(m_private->m_movie);
|
| - m_private->m_movie = 0;
|
| - m_private->m_loadState = 0;
|
| - }
|
| -
|
| - // Define a property array for NewMovieFromProperties.
|
| - QTNewMoviePropertyElement movieProps[9];
|
| - ItemCount moviePropCount = 0;
|
| -
|
| - bool boolTrue = true;
|
| -
|
| - // Disable streaming support for now.
|
| - CFStringRef scheme = CFURLCopyScheme(url);
|
| - bool isRTSP = CFStringHasPrefix(scheme, CFSTR("rtsp:"));
|
| - CFRelease(scheme);
|
| -
|
| - if (isRTSP) {
|
| - m_private->m_loadError = noMovieFound;
|
| - goto end;
|
| - }
|
| -
|
| - if (m_private->m_currentURL) {
|
| - if (m_private->m_currentURL != url) {
|
| - CFRelease(m_private->m_currentURL);
|
| - m_private->m_currentURL = url;
|
| - CFRetain(url);
|
| - }
|
| - } else {
|
| - m_private->m_currentURL = url;
|
| - CFRetain(url);
|
| - }
|
| -
|
| - // Add the movie data location to the property array
|
| - movieProps[moviePropCount].propClass = kQTPropertyClass_DataLocation;
|
| - movieProps[moviePropCount].propID = kQTDataLocationPropertyID_CFURL;
|
| - movieProps[moviePropCount].propValueSize = sizeof(m_private->m_currentURL);
|
| - movieProps[moviePropCount].propValueAddress = &(m_private->m_currentURL);
|
| - movieProps[moviePropCount].propStatus = 0;
|
| - moviePropCount++;
|
| -
|
| - movieProps[moviePropCount].propClass = kQTPropertyClass_MovieInstantiation;
|
| - movieProps[moviePropCount].propID = kQTMovieInstantiationPropertyID_DontAskUnresolvedDataRefs;
|
| - movieProps[moviePropCount].propValueSize = sizeof(boolTrue);
|
| - movieProps[moviePropCount].propValueAddress = &boolTrue;
|
| - movieProps[moviePropCount].propStatus = 0;
|
| - moviePropCount++;
|
| -
|
| - movieProps[moviePropCount].propClass = kQTPropertyClass_MovieInstantiation;
|
| - movieProps[moviePropCount].propID = kQTMovieInstantiationPropertyID_AsyncOK;
|
| - movieProps[moviePropCount].propValueSize = sizeof(boolTrue);
|
| - movieProps[moviePropCount].propValueAddress = &boolTrue;
|
| - movieProps[moviePropCount].propStatus = 0;
|
| - moviePropCount++;
|
| -
|
| - movieProps[moviePropCount].propClass = kQTPropertyClass_NewMovieProperty;
|
| - movieProps[moviePropCount].propID = kQTNewMoviePropertyID_Active;
|
| - movieProps[moviePropCount].propValueSize = sizeof(boolTrue);
|
| - movieProps[moviePropCount].propValueAddress = &boolTrue;
|
| - movieProps[moviePropCount].propStatus = 0;
|
| - moviePropCount++;
|
| -
|
| - movieProps[moviePropCount].propClass = kQTPropertyClass_NewMovieProperty;
|
| - movieProps[moviePropCount].propID = kQTNewMoviePropertyID_DontInteractWithUser;
|
| - movieProps[moviePropCount].propValueSize = sizeof(boolTrue);
|
| - movieProps[moviePropCount].propValueAddress = &boolTrue;
|
| - movieProps[moviePropCount].propStatus = 0;
|
| - moviePropCount++;
|
| -
|
| - movieProps[moviePropCount].propClass = kQTPropertyClass_MovieInstantiation;
|
| - movieProps[moviePropCount].propID = '!url';
|
| - movieProps[moviePropCount].propValueSize = sizeof(boolTrue);
|
| - movieProps[moviePropCount].propValueAddress = &boolTrue;
|
| - movieProps[moviePropCount].propStatus = 0;
|
| - moviePropCount++;
|
| -
|
| - movieProps[moviePropCount].propClass = kQTPropertyClass_MovieInstantiation;
|
| - movieProps[moviePropCount].propID = 'site';
|
| - movieProps[moviePropCount].propValueSize = sizeof(boolTrue);
|
| - movieProps[moviePropCount].propValueAddress = &boolTrue;
|
| - movieProps[moviePropCount].propStatus = 0;
|
| - moviePropCount++;
|
| -
|
| - movieProps[moviePropCount].propClass = kQTPropertyClass_Audio;
|
| - movieProps[moviePropCount].propID = kQTAudioPropertyID_RateChangesPreservePitch;
|
| - movieProps[moviePropCount].propValueSize = sizeof(preservesPitch);
|
| - movieProps[moviePropCount].propValueAddress = &preservesPitch;
|
| - movieProps[moviePropCount].propStatus = 0;
|
| - moviePropCount++;
|
| -
|
| - bool allowCaching = !m_private->m_privateBrowsing;
|
| - movieProps[moviePropCount].propClass = kQTPropertyClass_MovieInstantiation;
|
| - movieProps[moviePropCount].propID = 'pers';
|
| - movieProps[moviePropCount].propValueSize = sizeof(allowCaching);
|
| - movieProps[moviePropCount].propValueAddress = &allowCaching;
|
| - movieProps[moviePropCount].propStatus = 0;
|
| - moviePropCount++;
|
| -
|
| - ASSERT(moviePropCount <= WTF_ARRAY_LENGTH(movieProps));
|
| - m_private->m_loadError = NewMovieFromProperties(moviePropCount, movieProps, 0, 0, &m_private->m_movie);
|
| -
|
| -end:
|
| - m_private->startTask();
|
| - // get the load fail callback quickly
|
| - if (m_private->m_loadError)
|
| - QTMovieTask::sharedTask()->updateTaskTimer(0);
|
| - else {
|
| - OSType mode = kQTApertureMode_CleanAperture;
|
| -
|
| - // Set the aperture mode property on a movie to signal that we want aspect ratio
|
| - // and clean aperture dimensions. Don't worry about errors, we can't do anything if
|
| - // the installed version of QT doesn't support it and it isn't serious enough to
|
| - // warrant failing.
|
| - QTSetMovieProperty(m_private->m_movie, kQTPropertyClass_Visual, kQTVisualPropertyID_ApertureMode, sizeof(mode), &mode);
|
| - }
|
| -}
|
| -
|
| -void QTMovie::disableUnsupportedTracks(unsigned& enabledTrackCount, unsigned& totalTrackCount)
|
| -{
|
| - if (!m_private->m_movie) {
|
| - totalTrackCount = 0;
|
| - enabledTrackCount = 0;
|
| - return;
|
| - }
|
| -
|
| - static HashSet<OSType>* allowedTrackTypes = 0;
|
| - if (!allowedTrackTypes) {
|
| - allowedTrackTypes = new HashSet<OSType>;
|
| - allowedTrackTypes->add(VideoMediaType);
|
| - allowedTrackTypes->add(SoundMediaType);
|
| - allowedTrackTypes->add(TextMediaType);
|
| - allowedTrackTypes->add(BaseMediaType);
|
| - allowedTrackTypes->add(closedCaptionTrackType);
|
| - allowedTrackTypes->add(subTitleTrackType);
|
| - allowedTrackTypes->add(mpeg4ObjectDescriptionTrackType);
|
| - allowedTrackTypes->add(mpeg4SceneDescriptionTrackType);
|
| - allowedTrackTypes->add(TimeCodeMediaType);
|
| - allowedTrackTypes->add(TimeCode64MediaType);
|
| - }
|
| -
|
| - long trackCount = GetMovieTrackCount(m_private->m_movie);
|
| - enabledTrackCount = trackCount;
|
| - totalTrackCount = trackCount;
|
| -
|
| - // Track indexes are 1-based. yuck. These things must descend from old-
|
| - // school mac resources or something.
|
| - for (long trackIndex = 1; trackIndex <= trackCount; trackIndex++) {
|
| - // Grab the track at the current index. If there isn't one there, then
|
| - // we can move onto the next one.
|
| - Track currentTrack = GetMovieIndTrack(m_private->m_movie, trackIndex);
|
| - if (!currentTrack)
|
| - continue;
|
| -
|
| - // Check to see if the track is disabled already, we should move along.
|
| - // We don't need to re-disable it.
|
| - if (!GetTrackEnabled(currentTrack))
|
| - continue;
|
| -
|
| - // Grab the track's media. We're going to check to see if we need to
|
| - // disable the tracks. They could be unsupported.
|
| - Media trackMedia = GetTrackMedia(currentTrack);
|
| - if (!trackMedia)
|
| - continue;
|
| -
|
| - // Grab the media type for this track. Make sure that we don't
|
| - // get an error in doing so. If we do, then something really funky is
|
| - // wrong.
|
| - OSType mediaType;
|
| - GetMediaHandlerDescription(trackMedia, &mediaType, nil, nil);
|
| - OSErr mediaErr = GetMoviesError();
|
| - if (mediaErr != noErr)
|
| - continue;
|
| -
|
| - if (!allowedTrackTypes->contains(mediaType)) {
|
| -
|
| - // Different mpeg variants import as different track types so check for the "mpeg
|
| - // characteristic" instead of hard coding the (current) list of mpeg media types.
|
| - if (GetMovieIndTrackType(m_private->m_movie, 1, 'mpeg', movieTrackCharacteristic | movieTrackEnabledOnly))
|
| - continue;
|
| -
|
| - SetTrackEnabled(currentTrack, false);
|
| - --enabledTrackCount;
|
| - }
|
| -
|
| - // Grab the track reference count for chapters. This will tell us if it
|
| - // has chapter tracks in it. If there aren't any references, then we
|
| - // can move on the next track.
|
| - long referenceCount = GetTrackReferenceCount(currentTrack, kTrackReferenceChapterList);
|
| - if (referenceCount <= 0)
|
| - continue;
|
| -
|
| - long referenceIndex = 0;
|
| - while (1) {
|
| - // If we get nothing here, we've overstepped our bounds and can stop
|
| - // looking. Chapter indices here are 1-based as well - hence, the
|
| - // pre-increment.
|
| - referenceIndex++;
|
| - Track chapterTrack = GetTrackReference(currentTrack, kTrackReferenceChapterList, referenceIndex);
|
| - if (!chapterTrack)
|
| - break;
|
| -
|
| - // Try to grab the media for the track.
|
| - Media chapterMedia = GetTrackMedia(chapterTrack);
|
| - if (!chapterMedia)
|
| - continue;
|
| -
|
| - // Grab the media type for this track. Make sure that we don't
|
| - // get an error in doing so. If we do, then something really
|
| - // funky is wrong.
|
| - OSType mediaType;
|
| - GetMediaHandlerDescription(chapterMedia, &mediaType, nil, nil);
|
| - OSErr mediaErr = GetMoviesError();
|
| - if (mediaErr != noErr)
|
| - continue;
|
| -
|
| - // Check to see if the track is a video track. We don't care about
|
| - // other non-video tracks.
|
| - if (mediaType != VideoMediaType)
|
| - continue;
|
| -
|
| - // Check to see if the track is already disabled. If it is, we
|
| - // should move along.
|
| - if (!GetTrackEnabled(chapterTrack))
|
| - continue;
|
| -
|
| - // Disabled the evil, evil track.
|
| - SetTrackEnabled(chapterTrack, false);
|
| - --enabledTrackCount;
|
| - }
|
| - }
|
| -}
|
| -
|
| -bool QTMovie::isDisabled() const
|
| -{
|
| - return m_private->m_disabled;
|
| -}
|
| -
|
| -void QTMovie::setDisabled(bool b)
|
| -{
|
| - m_private->m_disabled = b;
|
| -}
|
| -
|
| -
|
| -bool QTMovie::hasVideo() const
|
| -{
|
| - if (!m_private->m_movie)
|
| - return false;
|
| - return (GetMovieIndTrackType(m_private->m_movie, 1, VisualMediaCharacteristic, movieTrackCharacteristic | movieTrackEnabledOnly));
|
| -}
|
| -
|
| -bool QTMovie::hasAudio() const
|
| -{
|
| - if (!m_private->m_movie)
|
| - return false;
|
| - return (GetMovieIndTrackType(m_private->m_movie, 1, AudioMediaCharacteristic, movieTrackCharacteristic | movieTrackEnabledOnly));
|
| -}
|
| -
|
| -QTTrackArray QTMovie::videoTracks() const
|
| -{
|
| - QTTrackArray tracks;
|
| - long trackIndex = 1;
|
| -
|
| - while (Track theTrack = GetMovieIndTrackType(m_private->m_movie, trackIndex++, VisualMediaCharacteristic, movieTrackCharacteristic | movieTrackEnabledOnly))
|
| - tracks.append(QTTrack::create(theTrack));
|
| -
|
| - return tracks;
|
| -}
|
| -
|
| -bool QTMovie::hasClosedCaptions() const
|
| -{
|
| - if (!m_private->m_movie)
|
| - return false;
|
| - return GetMovieIndTrackType(m_private->m_movie, 1, closedCaptionTrackType, movieTrackMediaType);
|
| -}
|
| -
|
| -void QTMovie::setClosedCaptionsVisible(bool visible)
|
| -{
|
| - if (!m_private->m_movie)
|
| - return;
|
| -
|
| - Track ccTrack = GetMovieIndTrackType(m_private->m_movie, 1, closedCaptionTrackType, movieTrackMediaType);
|
| - if (!ccTrack)
|
| - return;
|
| -
|
| - Boolean doDisplay = visible;
|
| - QTSetTrackProperty(ccTrack, closedCaptionTrackType, closedCaptionDisplayPropertyID, sizeof(doDisplay), &doDisplay);
|
| -}
|
| -
|
| -long QTMovie::timeScale() const
|
| -{
|
| - if (!m_private->m_movie)
|
| - return 0;
|
| -
|
| - return GetMovieTimeScale(m_private->m_movie);
|
| -}
|
| -
|
| -static void getMIMETypeCallBack(const char* type);
|
| -
|
| -static void initializeSupportedTypes()
|
| -{
|
| - if (gSupportedTypes)
|
| - return;
|
| -
|
| - gSupportedTypes = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
|
| - if (quickTimeVersion < minimumQuickTimeVersion) {
|
| - LOG_ERROR("QuickTime version %x detected, at least %x required. Returning empty list of supported media MIME types.", quickTimeVersion, minimumQuickTimeVersion);
|
| - return;
|
| - }
|
| -
|
| - // QuickTime doesn't have an importer for video/quicktime. Add it manually.
|
| - CFArrayAppendValue(gSupportedTypes, CFSTR("video/quicktime"));
|
| -
|
| - wkGetQuickTimeMIMETypeList(getMIMETypeCallBack);
|
| -}
|
| -
|
| -static void getMIMETypeCallBack(const char* type)
|
| -{
|
| - ASSERT(type);
|
| - CFStringRef cfType = CFStringCreateWithCString(kCFAllocatorDefault, type, kCFStringEncodingMacRoman);
|
| - if (!cfType)
|
| - return;
|
| -
|
| - // Filter out all non-audio or -video MIME Types, and only add each type once:
|
| - if (CFStringHasPrefix(cfType, CFSTR("audio/")) || CFStringHasPrefix(cfType, CFSTR("video/"))) {
|
| - CFRange range = CFRangeMake(0, CFArrayGetCount(gSupportedTypes));
|
| - if (!CFArrayContainsValue(gSupportedTypes, range, cfType))
|
| - CFArrayAppendValue(gSupportedTypes, cfType);
|
| - }
|
| -
|
| - CFRelease(cfType);
|
| -}
|
| -
|
| -unsigned QTMovie::countSupportedTypes()
|
| -{
|
| - initializeSupportedTypes();
|
| - return static_cast<unsigned>(CFArrayGetCount(gSupportedTypes));
|
| -}
|
| -
|
| -void QTMovie::getSupportedType(unsigned index, const UChar*& str, unsigned& len)
|
| -{
|
| - initializeSupportedTypes();
|
| - ASSERT(index < CFArrayGetCount(gSupportedTypes));
|
| -
|
| - // Allocate sufficient buffer to hold any MIME type
|
| - static UniChar* staticBuffer = 0;
|
| - if (!staticBuffer)
|
| - staticBuffer = new UniChar[32];
|
| -
|
| - CFStringRef cfstr = (CFStringRef)CFArrayGetValueAtIndex(gSupportedTypes, index);
|
| - len = CFStringGetLength(cfstr);
|
| - CFRange range = { 0, len };
|
| - CFStringGetCharacters(cfstr, range, staticBuffer);
|
| - str = reinterpret_cast<const UChar*>(staticBuffer);
|
| -
|
| -}
|
| -
|
| -CGAffineTransform QTMovie::getTransform() const
|
| -{
|
| - ASSERT(m_private->m_movie);
|
| - MatrixRecord m = {0};
|
| - GetMovieMatrix(m_private->m_movie, &m);
|
| -
|
| - ASSERT(!m.matrix[0][2]);
|
| - ASSERT(!m.matrix[1][2]);
|
| - CGAffineTransform transform = CGAffineTransformMake(
|
| - Fix2X(m.matrix[0][0]),
|
| - Fix2X(m.matrix[0][1]),
|
| - Fix2X(m.matrix[1][0]),
|
| - Fix2X(m.matrix[1][1]),
|
| - Fix2X(m.matrix[2][0]),
|
| - Fix2X(m.matrix[2][1]));
|
| - return transform;
|
| -}
|
| -
|
| -void QTMovie::setTransform(CGAffineTransform t)
|
| -{
|
| - ASSERT(m_private->m_movie);
|
| - MatrixRecord m = {{
|
| - {X2Fix(t.a), X2Fix(t.b), 0},
|
| - {X2Fix(t.c), X2Fix(t.d), 0},
|
| - {X2Fix(t.tx), X2Fix(t.ty), fract1},
|
| - }};
|
| -
|
| - SetMovieMatrix(m_private->m_movie, &m);
|
| - m_private->cacheMovieScale();
|
| -}
|
| -
|
| -void QTMovie::resetTransform()
|
| -{
|
| - ASSERT(m_private->m_movie);
|
| - SetMovieMatrix(m_private->m_movie, 0);
|
| - m_private->cacheMovieScale();
|
| -}
|
| -
|
| -void QTMovie::setPrivateBrowsingMode(bool privateBrowsing)
|
| -{
|
| - m_private->m_privateBrowsing = privateBrowsing;
|
| - if (m_private->m_movie) {
|
| - bool allowCaching = !m_private->m_privateBrowsing;
|
| - QTSetMovieProperty(m_private->m_movie, 'cach', 'pers', sizeof(allowCaching), &allowCaching);
|
| - }
|
| -}
|
| -
|
| -bool QTMovie::initializeQuickTime()
|
| -{
|
| - static bool initialized = false;
|
| - static bool initializationSucceeded = false;
|
| - if (!initialized) {
|
| - initialized = true;
|
| - // Initialize and check QuickTime version
|
| - OSErr result = InitializeQTML(kInitializeQTMLEnableDoubleBufferedSurface);
|
| - if (result == noErr)
|
| - result = Gestalt(gestaltQuickTime, &quickTimeVersion);
|
| - if (result != noErr) {
|
| - LOG_ERROR("No QuickTime available. Disabling <video> and <audio> support.");
|
| - return false;
|
| - }
|
| - if (quickTimeVersion < minimumQuickTimeVersion) {
|
| - LOG_ERROR("QuickTime version %x detected, at least %x required. Disabling <video> and <audio> support.", quickTimeVersion, minimumQuickTimeVersion);
|
| - return false;
|
| - }
|
| - EnterMovies();
|
| - initializationSucceeded = true;
|
| - }
|
| - return initializationSucceeded;
|
| -}
|
| -
|
| -Movie QTMovie::getMovieHandle() const
|
| -{
|
| - return m_private->m_movie;
|
| -}
|
| -
|
| -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
| -{
|
| - switch (fdwReason) {
|
| - case DLL_PROCESS_ATTACH:
|
| - return TRUE;
|
| - case DLL_PROCESS_DETACH:
|
| - case DLL_THREAD_ATTACH:
|
| - case DLL_THREAD_DETACH:
|
| - return FALSE;
|
| - }
|
| - ASSERT_NOT_REACHED();
|
| - return FALSE;
|
| -}
|
|
|