⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qtmoviewin.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2007, 2008, 2009 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 <windows.h>#include "QTMovieWin.h"// Put Movies.h first so build failures here point clearly to QuickTime#include <Movies.h>#include <QuickTimeComponents.h>#include <GXMath.h>#include <QTML.h>#include "QTMovieWinTimer.h"#include <wtf/Assertions.h>#include <wtf/HashSet.h>#include <wtf/Noncopyable.h>#include <wtf/Vector.h>using namespace std;static const long minimumQuickTimeVersion = 0x07300000; // 7.3// Resizing GWorlds is slow, give them a minimum size so size of small // videos can be animated smoothlystatic const int cGWorldMinWidth = 640;static const int cGWorldMinHeight = 360;static const float cNonContinuousTimeChange = 0.2f;union UppParam {    long longValue;    void* ptr;};static MovieDrawingCompleteUPP gMovieDrawingCompleteUPP = 0;static HashSet<QTMovieWinPrivate*>* gTaskList;static Vector<CFStringRef>* gSupportedTypes = 0;static SInt32 quickTimeVersion = 0;static void updateTaskTimer(int maxInterval = 1000){    if (!gTaskList->size()) {        stopSharedTimer();        return;        }        long intervalInMS;    QTGetTimeUntilNextTask(&intervalInMS, 1000);    if (intervalInMS > maxInterval)        intervalInMS = maxInterval;    setSharedTimerFireDelay(static_cast<float>(intervalInMS) / 1000);}class QTMovieWinPrivate : Noncopyable {public:    QTMovieWinPrivate();    ~QTMovieWinPrivate();    void task();    void startTask();    void endTask();    void createMovieController();    void registerDrawingCallback();    void drawingComplete();    void updateGWorld();    void createGWorld();    void deleteGWorld();    void clearGWorld();    void setSize(int, int);    QTMovieWin* m_movieWin;    Movie m_movie;    MovieController m_movieController;    bool m_tasking;    QTMovieWinClient* m_client;    long m_loadState;    bool m_ended;    bool m_seeking;    float m_lastMediaTime;    double m_lastLoadStateCheckTime;    int m_width;    int m_height;    bool m_visible;    GWorldPtr m_gWorld;    int m_gWorldWidth;    int m_gWorldHeight;    GWorldPtr m_savedGWorld;    long m_loadError;};QTMovieWinPrivate::QTMovieWinPrivate()    : m_movieWin(0)    , m_movie(0)    , m_movieController(0)    , m_tasking(false)    , m_client(0)    , 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_gWorld(0)    , m_gWorldWidth(0)    , m_gWorldHeight(0)    , m_savedGWorld(0)    , m_loadError(0){}QTMovieWinPrivate::~QTMovieWinPrivate(){    endTask();    if (m_gWorld)        deleteGWorld();    if (m_movieController)        DisposeMovieController(m_movieController);    if (m_movie)        DisposeMovie(m_movie);}static void taskTimerFired(){    // The hash content might change during task()    Vector<QTMovieWinPrivate*> tasks;    copyToVector(*gTaskList, tasks);    size_t count = tasks.size();    for (unsigned n = 0; n < count; ++n)        tasks[n]->task();    updateTaskTimer();}void QTMovieWinPrivate::startTask() {    if (m_tasking)        return;    if (!gTaskList)        gTaskList = new HashSet<QTMovieWinPrivate*>;    gTaskList->add(this);    m_tasking = true;    updateTaskTimer();}void QTMovieWinPrivate::endTask() {    if (!m_tasking)        return;    gTaskList->remove(this);    m_tasking = false;    updateTaskTimer();}void QTMovieWinPrivate::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 kMovieLoadStateComplete.        // This is different from QTKit API and seems strange.        long loadState = m_loadError ? kMovieLoadStateError : 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            if (loadState >= QTMovieLoadStateLoaded && m_loadState < QTMovieLoadStateLoaded && m_visible)                clearGWorld();            m_loadState = loadState;            if (!m_movieController && m_loadState >= kMovieLoadStateLoaded)                createMovieController();            m_client->movieLoadStateChanged(m_movieWin);        }        m_lastLoadStateCheckTime = systemTime();    }    bool ended = !!IsMovieDone(m_movie);    if (ended != m_ended) {        m_ended = ended;        if (m_client && ended)            m_client->movieEnded(m_movieWin);    }    float time = m_movieWin->currentTime();    if (time < m_lastMediaTime || time >= m_lastMediaTime + cNonContinuousTimeChange || m_seeking) {        m_seeking = false;        if (m_client)            m_client->movieTimeChanged(m_movieWin);    }    m_lastMediaTime = time;    if (m_loadError)        endTask();}void QTMovieWinPrivate::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;    MCSetControllerPort(m_movieController, m_gWorld);    MCSetControllerAttached(m_movieController, false);}void QTMovieWinPrivate::registerDrawingCallback(){    UppParam param;    param.ptr = this;    SetMovieDrawingCompleteProc(m_movie, movieDrawingCallWhenChanged, gMovieDrawingCompleteUPP, param.longValue);}void QTMovieWinPrivate::drawingComplete(){    if (!m_gWorld || m_loadState < kMovieLoadStateLoaded)        return;    m_client->movieNewImageAvailable(m_movieWin);}void QTMovieWinPrivate::updateGWorld(){    bool shouldBeVisible = m_visible;    if (!m_height || !m_width)        shouldBeVisible = false;    if (shouldBeVisible && !m_gWorld)        createGWorld();    else if (!shouldBeVisible && m_gWorld)        deleteGWorld();    else if (m_gWorld && (m_width > m_gWorldWidth || m_height > m_gWorldHeight)) {        // need a bigger, better gWorld        deleteGWorld();        createGWorld();    }}void QTMovieWinPrivate::createGWorld(){    ASSERT(!m_gWorld);    if (!m_movie)        return;    m_gWorldWidth = max(cGWorldMinWidth, m_width);    m_gWorldHeight = max(cGWorldMinHeight, m_height);    Rect bounds;     bounds.top = 0;    bounds.left = 0;     bounds.right = m_gWorldWidth;    bounds.bottom = m_gWorldHeight;    OSErr err = QTNewGWorld(&m_gWorld, k32BGRAPixelFormat, &bounds, NULL, NULL, NULL);     if (err)         return;    GetMovieGWorld(m_movie, &m_savedGWorld, 0);    if (m_movieController)        MCSetControllerPort(m_movieController, m_gWorld);    SetMovieGWorld(m_movie, m_gWorld, 0);    bounds.right = m_width;    bounds.bottom = m_height;    if (m_movieController)        MCSetControllerBoundsRect(m_movieController, &bounds);    SetMovieBox(m_movie, &bounds);}void QTMovieWinPrivate::clearGWorld(){    if (!m_movie||!m_gWorld)        return;    GrafPtr savePort;    GetPort(&savePort);     MacSetPort((GrafPtr)m_gWorld);    Rect bounds;     bounds.top = 0;    bounds.left = 0;     bounds.right = m_gWorldWidth;    bounds.bottom = m_gWorldHeight;    EraseRect(&bounds);    MacSetPort(savePort);}void QTMovieWinPrivate::setSize(int width, int height){    if (m_width == width && m_height == height)        return;    m_width = width;    m_height = height;    if (!m_movie)        return;    Rect bounds;     bounds.top = 0;    bounds.left = 0;     bounds.right = width;    bounds.bottom = height;    if (m_movieController)        MCSetControllerBoundsRect(m_movieController, &bounds);    SetMovieBox(m_movie, &bounds);    updateGWorld();}void QTMovieWinPrivate::deleteGWorld(){    ASSERT(m_gWorld);    if (m_movieController)        MCSetControllerPort(m_movieController, m_savedGWorld);    if (m_movie)        SetMovieGWorld(m_movie, m_savedGWorld, 0);    m_savedGWorld = 0;    DisposeGWorld(m_gWorld);     m_gWorld = 0;    m_gWorldWidth = 0;    m_gWorldHeight = 0;}QTMovieWin::QTMovieWin(QTMovieWinClient* client)    : m_private(new QTMovieWinPrivate()){    m_private->m_movieWin = this;    m_private->m_client = client;    initializeQuickTime();}QTMovieWin::~QTMovieWin(){    delete m_private;}void QTMovieWin::play(){    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 QTMovieWin::pause(){    if (m_private->m_movieController)        MCDoAction(m_private->m_movieController, mcActionPlay, 0);    else        StopMovie(m_private->m_movie);    updateTaskTimer();}float QTMovieWin::rate() const{    if (!m_private->m_movie)        return 0;    return FixedToFloat(GetMovieRate(m_private->m_movie));}void QTMovieWin::setRate(float rate){    if (!m_private->m_movie)        return;    if (m_private->m_movieController)        MCDoAction(m_private->m_movieController, mcActionPrerollAndPlay, (void *)FloatToFixed(rate));    else        SetMovieRate(m_private->m_movie, FloatToFixed(rate));    updateTaskTimer();}float QTMovieWin::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 QTMovieWin::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 QTMovieWin::setCurrentTime(float time) const{    if (!m_private->m_movie)        return;    m_private->m_seeking = true;    TimeScale scale = GetMovieTimeScale(m_private->m_movie);    if (m_private->m_movieController){        QTRestartAtTimeRecord restart = { time * scale , 0 };        MCDoAction(m_private->m_movieController, mcActionRestartAtTime, (void *)&restart);    } else        SetMovieTimeValue(m_private->m_movie, TimeValue(time * scale));    updateTaskTimer();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -