18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * Copyright (C) 2007, 2008, 2009, 2010, 2011 Apple, Inc.  All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    documentation and/or other materials provided with the distribution.
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
276c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen#include "QTMovie.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
296c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen#include "QTMovieTask.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "QTMovieWinTimer.h"
3168513a70bcd92384395513322f1b801e7bf9c729Steve Block#include <FixMath.h>
32d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <GXMath.h>
336c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen#include <Movies.h>
34d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <QTML.h>
35d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <QuickTimeComponents.h>
362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <WebKitSystemInterface/WebKitSystemInterface.h>
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/Assertions.h>
382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <wtf/MathExtras.h>
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/Noncopyable.h>
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/Vector.h>
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace std;
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const long minimumQuickTimeVersion = 0x07300000; // 7.3
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
46643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic const long closedCaptionTrackType = 'clcp';
47643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic const long subTitleTrackType = 'sbtl';
48643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic const long mpeg4ObjectDescriptionTrackType = 'odsm';
49643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic const long mpeg4SceneDescriptionTrackType = 'sdsm';
50643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic const long closedCaptionDisplayPropertyID = 'disp';
51643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Resizing GWorlds is slow, give them a minimum size so size of small
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// videos can be animated smoothly
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const int cGWorldMinWidth = 640;
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const int cGWorldMinHeight = 360;
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const float cNonContinuousTimeChange = 0.2f;
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectunion UppParam {
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    long longValue;
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void* ptr;
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
642fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic CFMutableArrayRef gSupportedTypes = 0;
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic SInt32 quickTimeVersion = 0;
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
67ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochclass QTMoviePrivate : public QTMovieTaskClient {
68ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    WTF_MAKE_NONCOPYABLE(QTMoviePrivate);
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectpublic:
706c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    QTMoviePrivate();
716c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    ~QTMoviePrivate();
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void task();
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void startTask();
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void endTask();
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void createMovieController();
775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void cacheMovieScale();
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
796c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    QTMovie* m_movieWin;
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Movie m_movie;
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    MovieController m_movieController;
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool m_tasking;
836c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    bool m_disabled;
846c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    Vector<QTMovieClient*> m_clients;
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    long m_loadState;
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool m_ended;
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool m_seeking;
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    float m_lastMediaTime;
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    double m_lastLoadStateCheckTime;
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int m_width;
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int m_height;
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool m_visible;
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    long m_loadError;
945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    float m_widthScaleFactor;
955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    float m_heightScaleFactor;
960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    CFURLRef m_currentURL;
970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    float m_timeToRestore;
980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    float m_rateToRestore;
9981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    bool m_privateBrowsing;
1005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#if !ASSERT_DISABLED
1015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    bool m_scaleCached;
1025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1056c2af9490927c3c5959b5cb07461b646f8b32f6cKristian MonsenQTMoviePrivate::QTMoviePrivate()
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    : m_movieWin(0)
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_movie(0)
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_movieController(0)
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_tasking(false)
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_loadState(0)
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_ended(false)
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_seeking(false)
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_lastMediaTime(0)
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_lastLoadStateCheckTime(0)
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_width(0)
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_height(0)
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_visible(false)
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_loadError(0)
1195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    , m_widthScaleFactor(1)
1205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    , m_heightScaleFactor(1)
1210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    , m_currentURL(0)
1220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    , m_timeToRestore(-1.0f)
1230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    , m_rateToRestore(-1.0f)
1246c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    , m_disabled(false)
12581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    , m_privateBrowsing(false)
1265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#if !ASSERT_DISABLED
1275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    , m_scaleCached(false)
1285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1326c2af9490927c3c5959b5cb07461b646f8b32f6cKristian MonsenQTMoviePrivate::~QTMoviePrivate()
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    endTask();
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_movieController)
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DisposeMovieController(m_movieController);
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_movie)
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DisposeMovie(m_movie);
1390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (m_currentURL)
1400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        CFRelease(m_currentURL);
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1436c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid QTMoviePrivate::startTask()
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1456c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (!m_tasking) {
1466c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QTMovieTask::sharedTask()->addTaskClient(this);
1476c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        m_tasking = true;
1486c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    }
1496c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    QTMovieTask::sharedTask()->updateTaskTimer();
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1526c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid QTMoviePrivate::endTask()
1535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
1546c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (m_tasking) {
1556c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QTMovieTask::sharedTask()->removeTaskClient(this);
1566c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        m_tasking = false;
1576c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    }
1586c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    QTMovieTask::sharedTask()->updateTaskTimer();
1595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
1605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1616c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid QTMoviePrivate::task()
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_tasking);
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_loadError) {
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_movieController)
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            MCIdle(m_movieController);
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            MoviesTask(m_movie, 0);
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // GetMovieLoadState documentation says that you should not call it more often than every quarter of a second.
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (systemTime() >= m_lastLoadStateCheckTime + 0.25 || m_loadError) {
1745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // If load fails QT's load state is QTMovieLoadStateComplete.
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // This is different from QTKit API and seems strange.
1765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        long loadState = m_loadError ? QTMovieLoadStateError : GetMovieLoadState(m_movie);
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (loadState != m_loadState) {
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // we only need to erase the movie gworld when the load state changes to loaded while it
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            //  is visible as the gworld is destroyed/created when visibility changes
1800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            bool shouldRestorePlaybackState = false;
1818a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            bool movieNewlyPlayable = loadState >= QTMovieLoadStateLoaded && m_loadState < QTMovieLoadStateLoaded;
1828a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            m_loadState = loadState;
1838a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            if (movieNewlyPlayable) {
1848a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block                cacheMovieScale();
1850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                shouldRestorePlaybackState = true;
1865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            if (!m_movieController && m_loadState >= QTMovieLoadStateLoaded)
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                createMovieController();
1906c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
1916c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            for (size_t i = 0; i < m_clients.size(); ++i)
1926c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen                m_clients[i]->movieLoadStateChanged(m_movieWin);
1930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            if (shouldRestorePlaybackState && m_timeToRestore != -1.0f) {
1950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                m_movieWin->setCurrentTime(m_timeToRestore);
1960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                m_timeToRestore = -1.0f;
1970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                m_movieWin->setRate(m_rateToRestore);
1980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                m_rateToRestore = -1.0f;
1990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            }
2000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2016c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            if (m_disabled) {
2025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                endTask();
2035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                return;
2045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_lastLoadStateCheckTime = systemTime();
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool ended = !!IsMovieDone(m_movie);
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ended != m_ended) {
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_ended = ended;
2126c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        if (ended) {
2136c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            for (size_t i = 0; i < m_clients.size(); ++i)
2146c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen               m_clients[i]->movieEnded(m_movieWin);
2156c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        }
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    float time = m_movieWin->currentTime();
2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (time < m_lastMediaTime || time >= m_lastMediaTime + cNonContinuousTimeChange || m_seeking) {
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_seeking = false;
2216c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        for (size_t i = 0; i < m_clients.size(); ++i)
2226c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            m_clients[i]->movieTimeChanged(m_movieWin);
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_lastMediaTime = time;
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_loadError)
2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        endTask();
2286c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    else
2296c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QTMovieTask::sharedTask()->updateTaskTimer();
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2326c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid QTMoviePrivate::createMovieController()
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Rect bounds;
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    long flags;
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_movie)
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_movieController)
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DisposeMovieController(m_movieController);
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    GetMovieBox(m_movie, &bounds);
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    flags = mcTopLeftMovie | mcNotVisible;
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_movieController = NewMovieController(m_movie, &bounds, flags);
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_movieController)
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2485ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
2495ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    // Disable automatic looping.
2505ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    MCDoAction(m_movieController, mcActionSetLooping, 0);
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2536c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid QTMoviePrivate::cacheMovieScale()
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2556c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    Rect naturalRect;
2566c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    Rect initialRect;
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2586c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    GetMovieNaturalBoundsRect(m_movie, &naturalRect);
2596c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    GetMovieBox(m_movie, &initialRect);
2605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2616c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    float naturalWidth = naturalRect.right - naturalRect.left;
2626c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    float naturalHeight = naturalRect.bottom - naturalRect.top;
2635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2646c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (naturalWidth)
2656c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        m_widthScaleFactor = (initialRect.right - initialRect.left) / naturalWidth;
2666c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (naturalHeight)
2676c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        m_heightScaleFactor = (initialRect.bottom - initialRect.top) / naturalHeight;
2685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#if !ASSERT_DISABLED
2696c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    m_scaleCached = true;
2705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif
2718a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block}
2728a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
2736c2af9490927c3c5959b5cb07461b646f8b32f6cKristian MonsenQTMovie::QTMovie(QTMovieClient* client)
2746c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    : m_private(new QTMoviePrivate())
2758a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block{
2766c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    m_private->m_movieWin = this;
2776c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (client)
2786c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        m_private->m_clients.append(client);
2796c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    initializeQuickTime();
2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2826c2af9490927c3c5959b5cb07461b646f8b32f6cKristian MonsenQTMovie::~QTMovie()
2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2846c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    delete m_private;
2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28768513a70bcd92384395513322f1b801e7bf9c729Steve Blockvoid QTMovie::disableComponent(uint32_t cd[5])
28868513a70bcd92384395513322f1b801e7bf9c729Steve Block{
28968513a70bcd92384395513322f1b801e7bf9c729Steve Block    ComponentDescription nullDesc = {'null', 'base', kAppleManufacturer, 0, 0};
29068513a70bcd92384395513322f1b801e7bf9c729Steve Block    Component nullComp = FindNextComponent(0, &nullDesc);
29168513a70bcd92384395513322f1b801e7bf9c729Steve Block    Component disabledComp = 0;
29268513a70bcd92384395513322f1b801e7bf9c729Steve Block
29368513a70bcd92384395513322f1b801e7bf9c729Steve Block    while (disabledComp = FindNextComponent(disabledComp, (ComponentDescription*)&cd[0]))
29468513a70bcd92384395513322f1b801e7bf9c729Steve Block        CaptureComponent(disabledComp, nullComp);
29568513a70bcd92384395513322f1b801e7bf9c729Steve Block}
29668513a70bcd92384395513322f1b801e7bf9c729Steve Block
2976c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid QTMovie::addClient(QTMovieClient* client)
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2996c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (client)
3006c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        m_private->m_clients.append(client);
3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3036c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid QTMovie::removeClient(QTMovieClient* client)
3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3056c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    size_t indexOfClient = m_private->m_clients.find(client);
3066c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (indexOfClient != notFound)
3076c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        m_private->m_clients.remove(indexOfClient);
3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3106c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid QTMovie::play()
3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    m_private->m_timeToRestore = -1.0f;
3130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_private->m_movieController)
3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        MCDoAction(m_private->m_movieController, mcActionPrerollAndPlay, (void *)GetMoviePreferredRate(m_private->m_movie));
3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        StartMovie(m_private->m_movie);
3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_private->startTask();
3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3216c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid QTMovie::pause()
3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    m_private->m_timeToRestore = -1.0f;
3240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_private->m_movieController)
3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        MCDoAction(m_private->m_movieController, mcActionPlay, 0);
3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        StopMovie(m_private->m_movie);
3296c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    QTMovieTask::sharedTask()->updateTaskTimer();
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3326c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenfloat QTMovie::rate() const
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_private->m_movie)
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return FixedToFloat(GetMovieRate(m_private->m_movie));
3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3396c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid QTMovie::setRate(float rate)
3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_private->m_movie)
3420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return;
3430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    m_private->m_timeToRestore = -1.0f;
3440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_private->m_movieController)
3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        MCDoAction(m_private->m_movieController, mcActionPrerollAndPlay, (void *)FloatToFixed(rate));
3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        SetMovieRate(m_private->m_movie, FloatToFixed(rate));
3496c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    QTMovieTask::sharedTask()->updateTaskTimer();
3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3526c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenfloat QTMovie::duration() const
3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_private->m_movie)
3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    TimeValue val = GetMovieDuration(m_private->m_movie);
3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    TimeScale scale = GetMovieTimeScale(m_private->m_movie);
3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return static_cast<float>(val) / scale;
3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3616c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenfloat QTMovie::currentTime() const
3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_private->m_movie)
3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    TimeValue val = GetMovieTime(m_private->m_movie, 0);
3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    TimeScale scale = GetMovieTimeScale(m_private->m_movie);
3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return static_cast<float>(val) / scale;
3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3706c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid QTMovie::setCurrentTime(float time) const
3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_private->m_movie)
3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
3740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    m_private->m_timeToRestore = -1.0f;
3760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_private->m_seeking = true;
3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    TimeScale scale = GetMovieTimeScale(m_private->m_movie);
3796c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (m_private->m_movieController) {
3802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        QTRestartAtTimeRecord restart = { lroundf(time * scale) , 0 };
3818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        MCDoAction(m_private->m_movieController, mcActionRestartAtTime, (void *)&restart);
3828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else
3832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        SetMovieTimeValue(m_private->m_movie, TimeValue(lroundf(time * scale)));
3846c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    QTMovieTask::sharedTask()->updateTaskTimer();
3858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3876c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid QTMovie::setVolume(float volume)
3888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_private->m_movie)
3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SetMovieVolume(m_private->m_movie, static_cast<short>(volume * 256));
3928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3946c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid QTMovie::setPreservesPitch(bool preservesPitch)
3950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
3960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!m_private->m_movie || !m_private->m_currentURL)
3970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return;
3980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    OSErr error;
4000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    bool prop = false;
4010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    error = QTGetMovieProperty(m_private->m_movie, kQTPropertyClass_Audio, kQTAudioPropertyID_RateChangesPreservePitch,
4030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                               sizeof(kQTAudioPropertyID_RateChangesPreservePitch), static_cast<QTPropertyValuePtr>(&prop), 0);
4040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (error || prop == preservesPitch)
4060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return;
4070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    m_private->m_timeToRestore = currentTime();
4090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    m_private->m_rateToRestore = rate();
4100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    load(m_private->m_currentURL, preservesPitch);
4110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
4120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4136c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenunsigned QTMovie::dataSize() const
4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_private->m_movie)
4168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return GetMovieDataSize(m_private->m_movie, 0, GetMovieDuration(m_private->m_movie));
4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4206c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenfloat QTMovie::maxTimeLoaded() const
4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_private->m_movie)
4238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    TimeValue val;
4258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    GetMaxLoadedTimeInMovie(m_private->m_movie, &val);
4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    TimeScale scale = GetMovieTimeScale(m_private->m_movie);
4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return static_cast<float>(val) / scale;
4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4306c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenlong QTMovie::loadState() const
4318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_private->m_loadState;
4338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4356c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid QTMovie::getNaturalSize(int& width, int& height)
4368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Rect rect = { 0, };
4388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_private->m_movie)
4408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        GetMovieNaturalBoundsRect(m_private->m_movie, &rect);
4415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    width = (rect.right - rect.left) * m_private->m_widthScaleFactor;
4425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    height = (rect.bottom - rect.top) * m_private->m_heightScaleFactor;
4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4452bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid QTMovie::loadPath(const UChar* url, int len, bool preservesPitch)
4462bde8e466a4451c7319e3a072d118917957d6554Steve Block{
4472bde8e466a4451c7319e3a072d118917957d6554Steve Block    CFStringRef urlStringRef = CFStringCreateWithCharacters(kCFAllocatorDefault, reinterpret_cast<const UniChar*>(url), len);
4482bde8e466a4451c7319e3a072d118917957d6554Steve Block    CFURLRef cfURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, urlStringRef, kCFURLWindowsPathStyle, false);
4492bde8e466a4451c7319e3a072d118917957d6554Steve Block
4502bde8e466a4451c7319e3a072d118917957d6554Steve Block    load(cfURL, preservesPitch);
4512bde8e466a4451c7319e3a072d118917957d6554Steve Block
4522bde8e466a4451c7319e3a072d118917957d6554Steve Block    CFRelease(cfURL);
4532bde8e466a4451c7319e3a072d118917957d6554Steve Block    CFRelease(urlStringRef);
4542bde8e466a4451c7319e3a072d118917957d6554Steve Block}
4552bde8e466a4451c7319e3a072d118917957d6554Steve Block
4566c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid QTMovie::load(const UChar* url, int len, bool preservesPitch)
4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    CFStringRef urlStringRef = CFStringCreateWithCharacters(kCFAllocatorDefault, reinterpret_cast<const UniChar*>(url), len);
4590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    CFURLRef cfURL = CFURLCreateWithString(kCFAllocatorDefault, urlStringRef, 0);
4600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    load(cfURL, preservesPitch);
4620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    CFRelease(cfURL);
4640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    CFRelease(urlStringRef);
4650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
4660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4676c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid QTMovie::load(CFURLRef url, bool preservesPitch)
4680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
4690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!url)
4700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return;
4710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_private->m_movie) {
4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_private->endTask();
4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_private->m_movieController)
4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            DisposeMovieController(m_private->m_movieController);
4768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_private->m_movieController = 0;
4778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DisposeMovie(m_private->m_movie);
4788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_private->m_movie = 0;
4790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        m_private->m_loadState = 0;
4808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // Define a property array for NewMovieFromProperties.
48381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    QTNewMoviePropertyElement movieProps[9];
4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ItemCount moviePropCount = 0;
4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool boolTrue = true;
4878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Disable streaming support for now.
4890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    CFStringRef scheme = CFURLCopyScheme(url);
4900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    bool isRTSP = CFStringHasPrefix(scheme, CFSTR("rtsp:"));
4910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    CFRelease(scheme);
4920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (isRTSP) {
4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_private->m_loadError = noMovieFound;
4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        goto end;
4968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (m_private->m_currentURL) {
4990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (m_private->m_currentURL != url) {
5000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            CFRelease(m_private->m_currentURL);
5010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            m_private->m_currentURL = url;
5020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            CFRetain(url);
5030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
5040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    } else {
5050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        m_private->m_currentURL = url;
5060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        CFRetain(url);
5070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
5088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Add the movie data location to the property array
5108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propClass = kQTPropertyClass_DataLocation;
5118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propID = kQTDataLocationPropertyID_CFURL;
5120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    movieProps[moviePropCount].propValueSize = sizeof(m_private->m_currentURL);
5130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    movieProps[moviePropCount].propValueAddress = &(m_private->m_currentURL);
5148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propStatus = 0;
5158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    moviePropCount++;
5168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propClass = kQTPropertyClass_MovieInstantiation;
5188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propID = kQTMovieInstantiationPropertyID_DontAskUnresolvedDataRefs;
5198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propValueSize = sizeof(boolTrue);
5208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propValueAddress = &boolTrue;
5218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propStatus = 0;
5228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    moviePropCount++;
5238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propClass = kQTPropertyClass_MovieInstantiation;
5258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propID = kQTMovieInstantiationPropertyID_AsyncOK;
5268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propValueSize = sizeof(boolTrue);
5278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propValueAddress = &boolTrue;
5288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propStatus = 0;
5298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    moviePropCount++;
5308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propClass = kQTPropertyClass_NewMovieProperty;
5328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propID = kQTNewMoviePropertyID_Active;
5338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propValueSize = sizeof(boolTrue);
5348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propValueAddress = &boolTrue;
5358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propStatus = 0;
5368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    moviePropCount++;
5378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propClass = kQTPropertyClass_NewMovieProperty;
5398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propID = kQTNewMoviePropertyID_DontInteractWithUser;
5408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propValueSize = sizeof(boolTrue);
5418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propValueAddress = &boolTrue;
5428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propStatus = 0;
5438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    moviePropCount++;
5448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propClass = kQTPropertyClass_MovieInstantiation;
5468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propID = '!url';
5478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propValueSize = sizeof(boolTrue);
5488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propValueAddress = &boolTrue;
5498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propStatus = 0;
5508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    moviePropCount++;
5518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propClass = kQTPropertyClass_MovieInstantiation;
5538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propID = 'site';
5548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propValueSize = sizeof(boolTrue);
5558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propValueAddress = &boolTrue;
5568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    movieProps[moviePropCount].propStatus = 0;
5570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    moviePropCount++;
5580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    movieProps[moviePropCount].propClass = kQTPropertyClass_Audio;
5600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    movieProps[moviePropCount].propID = kQTAudioPropertyID_RateChangesPreservePitch;
5610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    movieProps[moviePropCount].propValueSize = sizeof(preservesPitch);
5620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    movieProps[moviePropCount].propValueAddress = &preservesPitch;
5630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    movieProps[moviePropCount].propStatus = 0;
5648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    moviePropCount++;
5658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
56681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    bool allowCaching = !m_private->m_privateBrowsing;
56781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    movieProps[moviePropCount].propClass = kQTPropertyClass_MovieInstantiation;
56881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    movieProps[moviePropCount].propID = 'pers';
56981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    movieProps[moviePropCount].propValueSize = sizeof(allowCaching);
57081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    movieProps[moviePropCount].propValueAddress = &allowCaching;
57181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    movieProps[moviePropCount].propStatus = 0;
57281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    moviePropCount++;
57381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
5744576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    ASSERT(moviePropCount <= WTF_ARRAY_LENGTH(movieProps));
575d0825bca7fe65beaee391d30da42e937db621564Steve Block    m_private->m_loadError = NewMovieFromProperties(moviePropCount, movieProps, 0, 0, &m_private->m_movie);
5768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectend:
5788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_private->startTask();
5798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // get the load fail callback quickly
5808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_private->m_loadError)
5816c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QTMovieTask::sharedTask()->updateTaskTimer(0);
5825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    else {
5835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        OSType mode = kQTApertureMode_CleanAperture;
5845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
5855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // Set the aperture mode property on a movie to signal that we want aspect ratio
5865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // and clean aperture dimensions. Don't worry about errors, we can't do anything if
5875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // the installed version of QT doesn't support it and it isn't serious enough to
5885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // warrant failing.
5895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        QTSetMovieProperty(m_private->m_movie, kQTPropertyClass_Visual, kQTVisualPropertyID_ApertureMode, sizeof(mode), &mode);
5905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
5918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5936c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid QTMovie::disableUnsupportedTracks(unsigned& enabledTrackCount, unsigned& totalTrackCount)
5948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_private->m_movie) {
5965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        totalTrackCount = 0;
5978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        enabledTrackCount = 0;
5988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
5998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static HashSet<OSType>* allowedTrackTypes = 0;
6028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!allowedTrackTypes) {
6038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        allowedTrackTypes = new HashSet<OSType>;
6048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        allowedTrackTypes->add(VideoMediaType);
6058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        allowedTrackTypes->add(SoundMediaType);
6068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        allowedTrackTypes->add(TextMediaType);
6078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        allowedTrackTypes->add(BaseMediaType);
608643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        allowedTrackTypes->add(closedCaptionTrackType);
609643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        allowedTrackTypes->add(subTitleTrackType);
610643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        allowedTrackTypes->add(mpeg4ObjectDescriptionTrackType);
611643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        allowedTrackTypes->add(mpeg4SceneDescriptionTrackType);
6125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        allowedTrackTypes->add(TimeCodeMediaType);
6135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        allowedTrackTypes->add(TimeCode64MediaType);
6148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    long trackCount = GetMovieTrackCount(m_private->m_movie);
6178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    enabledTrackCount = trackCount;
6185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    totalTrackCount = trackCount;
6195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
6208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Track indexes are 1-based. yuck. These things must descend from old-
6218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // school mac resources or something.
6228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (long trackIndex = 1; trackIndex <= trackCount; trackIndex++) {
6238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Grab the track at the current index. If there isn't one there, then
6248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // we can move onto the next one.
6258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Track currentTrack = GetMovieIndTrack(m_private->m_movie, trackIndex);
6268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!currentTrack)
6278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
6288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Check to see if the track is disabled already, we should move along.
6308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We don't need to re-disable it.
6318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!GetTrackEnabled(currentTrack))
6328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
6338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Grab the track's media. We're going to check to see if we need to
6358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // disable the tracks. They could be unsupported.
6368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Media trackMedia = GetTrackMedia(currentTrack);
6378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!trackMedia)
6388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
6398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Grab the media type for this track. Make sure that we don't
6418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // get an error in doing so. If we do, then something really funky is
6428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // wrong.
6438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        OSType mediaType;
6448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        GetMediaHandlerDescription(trackMedia, &mediaType, nil, nil);
6458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        OSErr mediaErr = GetMoviesError();
6468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (mediaErr != noErr)
6478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
6488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!allowedTrackTypes->contains(mediaType)) {
6508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
6518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // Different mpeg variants import as different track types so check for the "mpeg
6528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // characteristic" instead of hard coding the (current) list of mpeg media types.
6538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (GetMovieIndTrackType(m_private->m_movie, 1, 'mpeg', movieTrackCharacteristic | movieTrackEnabledOnly))
6548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                continue;
6558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
6568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            SetTrackEnabled(currentTrack, false);
6578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            --enabledTrackCount;
6588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
6598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Grab the track reference count for chapters. This will tell us if it
6618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // has chapter tracks in it. If there aren't any references, then we
6628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // can move on the next track.
6638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        long referenceCount = GetTrackReferenceCount(currentTrack, kTrackReferenceChapterList);
6648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (referenceCount <= 0)
6658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
6668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        long referenceIndex = 0;
6688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (1) {
6698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // If we get nothing here, we've overstepped our bounds and can stop
6708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // looking. Chapter indices here are 1-based as well - hence, the
6718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // pre-increment.
6728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            referenceIndex++;
6738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            Track chapterTrack = GetTrackReference(currentTrack, kTrackReferenceChapterList, referenceIndex);
6748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!chapterTrack)
6758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
6768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Try to grab the media for the track.
6788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            Media chapterMedia = GetTrackMedia(chapterTrack);
6798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!chapterMedia)
6808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
6818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Grab the media type for this track. Make sure that we don't
6838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // get an error in doing so. If we do, then something really
6848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // funky is wrong.
6858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            OSType mediaType;
6868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            GetMediaHandlerDescription(chapterMedia, &mediaType, nil, nil);
6878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            OSErr mediaErr = GetMoviesError();
6888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (mediaErr != noErr)
6898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
6908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Check to see if the track is a video track. We don't care about
6928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // other non-video tracks.
6938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (mediaType != VideoMediaType)
6948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
6958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Check to see if the track is already disabled. If it is, we
6978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // should move along.
6988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!GetTrackEnabled(chapterTrack))
6998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
7008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Disabled the evil, evil track.
7028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            SetTrackEnabled(chapterTrack, false);
7038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            --enabledTrackCount;
7048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7086c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenbool QTMovie::isDisabled() const
7096c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen{
7106c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    return m_private->m_disabled;
7116c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen}
7126c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
7136c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid QTMovie::setDisabled(bool b)
7145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
7156c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    m_private->m_disabled = b;
7165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
7175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
718635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
7196c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenbool QTMovie::hasVideo() const
720635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
721635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!m_private->m_movie)
722635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return false;
723635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return (GetMovieIndTrackType(m_private->m_movie, 1, VisualMediaCharacteristic, movieTrackCharacteristic | movieTrackEnabledOnly));
724635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
725635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
7266c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenbool QTMovie::hasAudio() const
727231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
728231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!m_private->m_movie)
729231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return false;
730231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return (GetMovieIndTrackType(m_private->m_movie, 1, AudioMediaCharacteristic, movieTrackCharacteristic | movieTrackEnabledOnly));
731231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
732231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
73368513a70bcd92384395513322f1b801e7bf9c729Steve BlockQTTrackArray QTMovie::videoTracks() const
73468513a70bcd92384395513322f1b801e7bf9c729Steve Block{
73568513a70bcd92384395513322f1b801e7bf9c729Steve Block    QTTrackArray tracks;
73668513a70bcd92384395513322f1b801e7bf9c729Steve Block    long trackIndex = 1;
73768513a70bcd92384395513322f1b801e7bf9c729Steve Block
73868513a70bcd92384395513322f1b801e7bf9c729Steve Block    while (Track theTrack = GetMovieIndTrackType(m_private->m_movie, trackIndex++, VisualMediaCharacteristic, movieTrackCharacteristic | movieTrackEnabledOnly))
73968513a70bcd92384395513322f1b801e7bf9c729Steve Block        tracks.append(QTTrack::create(theTrack));
74068513a70bcd92384395513322f1b801e7bf9c729Steve Block
74168513a70bcd92384395513322f1b801e7bf9c729Steve Block    return tracks;
74268513a70bcd92384395513322f1b801e7bf9c729Steve Block}
743643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
7446c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenbool QTMovie::hasClosedCaptions() const
745643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
746643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!m_private->m_movie)
747643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return false;
748643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return GetMovieIndTrackType(m_private->m_movie, 1, closedCaptionTrackType, movieTrackMediaType);
749643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
750643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
7516c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid QTMovie::setClosedCaptionsVisible(bool visible)
752643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
753643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!m_private->m_movie)
754643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return;
755643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
756643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    Track ccTrack = GetMovieIndTrackType(m_private->m_movie, 1, closedCaptionTrackType, movieTrackMediaType);
757643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!ccTrack)
758643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return;
759643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
760643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    Boolean doDisplay = visible;
761643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    QTSetTrackProperty(ccTrack, closedCaptionTrackType, closedCaptionDisplayPropertyID, sizeof(doDisplay), &doDisplay);
762643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
763643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
76428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhulong QTMovie::timeScale() const
76528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu{
76628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (!m_private->m_movie)
76728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        return 0;
76828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
76928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    return GetMovieTimeScale(m_private->m_movie);
77028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu}
77128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
7722fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic void getMIMETypeCallBack(const char* type);
7732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
7748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void initializeSupportedTypes()
7758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (gSupportedTypes)
7778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
7788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    gSupportedTypes = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
7808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (quickTimeVersion < minimumQuickTimeVersion) {
7818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        LOG_ERROR("QuickTime version %x detected, at least %x required. Returning empty list of supported media MIME types.", quickTimeVersion, minimumQuickTimeVersion);
7828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
7838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // QuickTime doesn't have an importer for video/quicktime. Add it manually.
7862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    CFArrayAppendValue(gSupportedTypes, CFSTR("video/quicktime"));
7872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
7882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    wkGetQuickTimeMIMETypeList(getMIMETypeCallBack);
7892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
7908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7912fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic void getMIMETypeCallBack(const char* type)
7922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
7932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ASSERT(type);
7942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    CFStringRef cfType = CFStringCreateWithCString(kCFAllocatorDefault, type, kCFStringEncodingMacRoman);
7952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!cfType)
7962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return;
7978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // Filter out all non-audio or -video MIME Types, and only add each type once:
7992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (CFStringHasPrefix(cfType, CFSTR("audio/")) || CFStringHasPrefix(cfType, CFSTR("video/"))) {
8002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        CFRange range = CFRangeMake(0, CFArrayGetCount(gSupportedTypes));
8012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (!CFArrayContainsValue(gSupportedTypes, range, cfType))
8022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            CFArrayAppendValue(gSupportedTypes, cfType);
8038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
8042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
8052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    CFRelease(cfType);
8068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8086c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenunsigned QTMovie::countSupportedTypes()
8098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    initializeSupportedTypes();
8112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return static_cast<unsigned>(CFArrayGetCount(gSupportedTypes));
8128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8146c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid QTMovie::getSupportedType(unsigned index, const UChar*& str, unsigned& len)
8158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    initializeSupportedTypes();
8172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ASSERT(index < CFArrayGetCount(gSupportedTypes));
8188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Allocate sufficient buffer to hold any MIME type
8208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static UniChar* staticBuffer = 0;
8218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!staticBuffer)
8228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        staticBuffer = new UniChar[32];
8238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    CFStringRef cfstr = (CFStringRef)CFArrayGetValueAtIndex(gSupportedTypes, index);
8258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    len = CFStringGetLength(cfstr);
8268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CFRange range = { 0, len };
8278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CFStringGetCharacters(cfstr, range, staticBuffer);
8288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    str = reinterpret_cast<const UChar*>(staticBuffer);
8298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
83268513a70bcd92384395513322f1b801e7bf9c729Steve BlockCGAffineTransform QTMovie::getTransform() const
83368513a70bcd92384395513322f1b801e7bf9c729Steve Block{
83468513a70bcd92384395513322f1b801e7bf9c729Steve Block    ASSERT(m_private->m_movie);
83568513a70bcd92384395513322f1b801e7bf9c729Steve Block    MatrixRecord m = {0};
83668513a70bcd92384395513322f1b801e7bf9c729Steve Block    GetMovieMatrix(m_private->m_movie, &m);
83768513a70bcd92384395513322f1b801e7bf9c729Steve Block
83868513a70bcd92384395513322f1b801e7bf9c729Steve Block    ASSERT(!m.matrix[0][2]);
83968513a70bcd92384395513322f1b801e7bf9c729Steve Block    ASSERT(!m.matrix[1][2]);
84068513a70bcd92384395513322f1b801e7bf9c729Steve Block    CGAffineTransform transform = CGAffineTransformMake(
84168513a70bcd92384395513322f1b801e7bf9c729Steve Block        Fix2X(m.matrix[0][0]),
84268513a70bcd92384395513322f1b801e7bf9c729Steve Block        Fix2X(m.matrix[0][1]),
84368513a70bcd92384395513322f1b801e7bf9c729Steve Block        Fix2X(m.matrix[1][0]),
84468513a70bcd92384395513322f1b801e7bf9c729Steve Block        Fix2X(m.matrix[1][1]),
84568513a70bcd92384395513322f1b801e7bf9c729Steve Block        Fix2X(m.matrix[2][0]),
84668513a70bcd92384395513322f1b801e7bf9c729Steve Block        Fix2X(m.matrix[2][1]));
84768513a70bcd92384395513322f1b801e7bf9c729Steve Block    return transform;
84868513a70bcd92384395513322f1b801e7bf9c729Steve Block}
84968513a70bcd92384395513322f1b801e7bf9c729Steve Block
85068513a70bcd92384395513322f1b801e7bf9c729Steve Blockvoid QTMovie::setTransform(CGAffineTransform t)
85168513a70bcd92384395513322f1b801e7bf9c729Steve Block{
85268513a70bcd92384395513322f1b801e7bf9c729Steve Block    ASSERT(m_private->m_movie);
85368513a70bcd92384395513322f1b801e7bf9c729Steve Block    MatrixRecord m = {{
85468513a70bcd92384395513322f1b801e7bf9c729Steve Block        {X2Fix(t.a), X2Fix(t.b), 0},
85568513a70bcd92384395513322f1b801e7bf9c729Steve Block        {X2Fix(t.c), X2Fix(t.d), 0},
85668513a70bcd92384395513322f1b801e7bf9c729Steve Block        {X2Fix(t.tx), X2Fix(t.ty), fract1},
85768513a70bcd92384395513322f1b801e7bf9c729Steve Block    }};
85868513a70bcd92384395513322f1b801e7bf9c729Steve Block
85968513a70bcd92384395513322f1b801e7bf9c729Steve Block    SetMovieMatrix(m_private->m_movie, &m);
86068513a70bcd92384395513322f1b801e7bf9c729Steve Block    m_private->cacheMovieScale();
86168513a70bcd92384395513322f1b801e7bf9c729Steve Block}
86268513a70bcd92384395513322f1b801e7bf9c729Steve Block
86368513a70bcd92384395513322f1b801e7bf9c729Steve Blockvoid QTMovie::resetTransform()
86468513a70bcd92384395513322f1b801e7bf9c729Steve Block{
86568513a70bcd92384395513322f1b801e7bf9c729Steve Block    ASSERT(m_private->m_movie);
86668513a70bcd92384395513322f1b801e7bf9c729Steve Block    SetMovieMatrix(m_private->m_movie, 0);
86768513a70bcd92384395513322f1b801e7bf9c729Steve Block    m_private->cacheMovieScale();
86868513a70bcd92384395513322f1b801e7bf9c729Steve Block}
86968513a70bcd92384395513322f1b801e7bf9c729Steve Block
87081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid QTMovie::setPrivateBrowsingMode(bool privateBrowsing)
87181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
87281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_private->m_privateBrowsing = privateBrowsing;
87381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_private->m_movie) {
87481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        bool allowCaching = !m_private->m_privateBrowsing;
87581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        QTSetMovieProperty(m_private->m_movie, 'cach', 'pers', sizeof(allowCaching), &allowCaching);
87681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
87781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
87868513a70bcd92384395513322f1b801e7bf9c729Steve Block
8796c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenbool QTMovie::initializeQuickTime()
8808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static bool initialized = false;
8828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static bool initializationSucceeded = false;
8838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!initialized) {
8848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        initialized = true;
8858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Initialize and check QuickTime version
886d0825bca7fe65beaee391d30da42e937db621564Steve Block        OSErr result = InitializeQTML(kInitializeQTMLEnableDoubleBufferedSurface);
8878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (result == noErr)
8888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            result = Gestalt(gestaltQuickTime, &quickTimeVersion);
8898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (result != noErr) {
8908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            LOG_ERROR("No QuickTime available. Disabling <video> and <audio> support.");
8918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return false;
8928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
8938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (quickTimeVersion < minimumQuickTimeVersion) {
8948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            LOG_ERROR("QuickTime version %x detected, at least %x required. Disabling <video> and <audio> support.", quickTimeVersion, minimumQuickTimeVersion);
8958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return false;
8968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
8978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        EnterMovies();
8988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        initializationSucceeded = true;
8998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return initializationSucceeded;
9018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9036c2af9490927c3c5959b5cb07461b646f8b32f6cKristian MonsenMovie QTMovie::getMovieHandle() const
904d0825bca7fe65beaee391d30da42e937db621564Steve Block{
9056c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    return m_private->m_movie;
906d0825bca7fe65beaee391d30da42e937db621564Steve Block}
907d0825bca7fe65beaee391d30da42e937db621564Steve Block
9088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectBOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
9098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    switch (fdwReason) {
911d0825bca7fe65beaee391d30da42e937db621564Steve Block    case DLL_PROCESS_ATTACH:
912d0825bca7fe65beaee391d30da42e937db621564Steve Block        return TRUE;
913d0825bca7fe65beaee391d30da42e937db621564Steve Block    case DLL_PROCESS_DETACH:
914d0825bca7fe65beaee391d30da42e937db621564Steve Block    case DLL_THREAD_ATTACH:
915d0825bca7fe65beaee391d30da42e937db621564Steve Block    case DLL_THREAD_DETACH:
916d0825bca7fe65beaee391d30da42e937db621564Steve Block        return FALSE;
9178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT_NOT_REACHED();
9198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return FALSE;
9208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
921