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; |
-} |