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

📄 mediaplayerprivatequicktimewin.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
字号:
/* * 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"#if ENABLE(VIDEO)#include "MediaPlayerPrivateQuickTimeWin.h"#include "GraphicsContext.h"#include "KURL.h"#include "QTMovieWin.h"#include "ScrollView.h"#include "StringHash.h"#include <wtf/HashSet.h>#include <wtf/MathExtras.h>#include <wtf/StdLibExtras.h>#if DRAW_FRAME_RATE#include "Font.h"#include "FrameView.h"#include "Frame.h"#include "Document.h"#include "RenderObject.h"#include "RenderStyle.h"#include "Windows.h"#endifusing namespace std;namespace WebCore {MediaPlayerPrivateInterface* MediaPlayerPrivate::create(MediaPlayer* player) {     return new MediaPlayerPrivate(player);}void MediaPlayerPrivate::registerMediaEngine(MediaEngineRegistrar registrar){    if (isAvailable())        registrar(create, getSupportedTypes, supportsType);}static const double endPointTimerInterval = 0.020;MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)    : m_player(player)    , m_seekTo(-1)    , m_endTime(numeric_limits<float>::infinity())    , m_seekTimer(this, &MediaPlayerPrivate::seekTimerFired)    , m_endPointTimer(this, &MediaPlayerPrivate::endPointTimerFired)    , m_networkState(MediaPlayer::Empty)    , m_readyState(MediaPlayer::DataUnavailable)    , m_startedPlaying(false)    , m_isStreaming(false)#if DRAW_FRAME_RATE    , m_frameCountWhilePlaying(0)    , m_timeStartedPlaying(0)    , m_timeStoppedPlaying(0)#endif{}MediaPlayerPrivate::~MediaPlayerPrivate(){}void MediaPlayerPrivate::load(const String& url){    if (!QTMovieWin::initializeQuickTime()) {        m_networkState = MediaPlayer::LoadFailed;        m_player->networkStateChanged();        return;    }    if (m_networkState != MediaPlayer::Loading) {        m_networkState = MediaPlayer::Loading;        m_player->networkStateChanged();    }    if (m_readyState != MediaPlayer::DataUnavailable) {        m_readyState = MediaPlayer::DataUnavailable;        m_player->readyStateChanged();    }    cancelSeek();    m_endPointTimer.stop();    m_qtMovie.set(new QTMovieWin(this));    m_qtMovie->load(url.characters(), url.length());    m_qtMovie->setVolume(m_player->volume());    m_qtMovie->setVisible(m_player->visible());}void MediaPlayerPrivate::play(){    if (!m_qtMovie)        return;    m_startedPlaying = true;#if DRAW_FRAME_RATE    m_frameCountWhilePlaying = 0;#endif    m_qtMovie->play();    startEndPointTimerIfNeeded();}void MediaPlayerPrivate::pause(){    if (!m_qtMovie)        return;    m_startedPlaying = false;#if DRAW_FRAME_RATE    m_timeStoppedPlaying = GetTickCount();#endif    m_qtMovie->pause();    m_endPointTimer.stop();}float MediaPlayerPrivate::duration() const{    if (!m_qtMovie)        return 0;    return m_qtMovie->duration();}float MediaPlayerPrivate::currentTime() const{    if (!m_qtMovie)        return 0;    return min(m_qtMovie->currentTime(), m_endTime);}void MediaPlayerPrivate::seek(float time){    cancelSeek();        if (!m_qtMovie)        return;        if (time > duration())        time = duration();        m_seekTo = time;    if (maxTimeLoaded() >= m_seekTo)        doSeek();    else         m_seekTimer.start(0, 0.5f);}    void MediaPlayerPrivate::doSeek() {    float oldRate = m_qtMovie->rate();    m_qtMovie->setRate(0);    m_qtMovie->setCurrentTime(m_seekTo);    float timeAfterSeek = currentTime();    // restore playback only if not at end, othewise QTMovie will loop    if (timeAfterSeek < duration() && timeAfterSeek < m_endTime)        m_qtMovie->setRate(oldRate);    cancelSeek();}void MediaPlayerPrivate::cancelSeek(){    m_seekTo = -1;    m_seekTimer.stop();}void MediaPlayerPrivate::seekTimerFired(Timer<MediaPlayerPrivate>*){            if (!m_qtMovie || !seeking() || currentTime() == m_seekTo) {        cancelSeek();        updateStates();        m_player->timeChanged();         return;    }         if (maxTimeLoaded() >= m_seekTo)        doSeek();    else {        MediaPlayer::NetworkState state = networkState();        if (state == MediaPlayer::Empty || state == MediaPlayer::Loaded) {            cancelSeek();            updateStates();            m_player->timeChanged();        }    }}void MediaPlayerPrivate::setEndTime(float time){    m_endTime = time;    startEndPointTimerIfNeeded();}void MediaPlayerPrivate::startEndPointTimerIfNeeded(){    if (m_endTime < duration() && m_startedPlaying && !m_endPointTimer.isActive())        m_endPointTimer.startRepeating(endPointTimerInterval);}void MediaPlayerPrivate::endPointTimerFired(Timer<MediaPlayerPrivate>*){    float time = currentTime();    if (time >= m_endTime) {        pause();        didEnd();    }}bool MediaPlayerPrivate::paused() const{    if (!m_qtMovie)        return true;    return m_qtMovie->rate() == 0.0f;}bool MediaPlayerPrivate::seeking() const{    if (!m_qtMovie)        return false;    return m_seekTo >= 0;}IntSize MediaPlayerPrivate::naturalSize() const{    if (!m_qtMovie)        return IntSize();    int width;    int height;    m_qtMovie->getNaturalSize(width, height);    return IntSize(width, height);}bool MediaPlayerPrivate::hasVideo() const{    if (!m_qtMovie)        return false;    return m_qtMovie->hasVideo();}void MediaPlayerPrivate::setVolume(float volume){    if (!m_qtMovie)        return;    m_qtMovie->setVolume(volume);}void MediaPlayerPrivate::setRate(float rate){    if (!m_qtMovie)        return;    if (!paused())        m_qtMovie->setRate(rate);}int MediaPlayerPrivate::dataRate() const{    // This is not used at the moment    return 0;}float MediaPlayerPrivate::maxTimeBuffered() const{    // rtsp streams are not buffered    return m_isStreaming ? 0 : maxTimeLoaded();}float MediaPlayerPrivate::maxTimeSeekable() const{    // infinite duration means live stream    return !isfinite(duration()) ? 0 : maxTimeLoaded();}float MediaPlayerPrivate::maxTimeLoaded() const{    if (!m_qtMovie)        return 0;    return m_qtMovie->maxTimeLoaded(); }unsigned MediaPlayerPrivate::bytesLoaded() const{    if (!m_qtMovie)        return 0;    float dur = duration();    float maxTime = maxTimeLoaded();    if (!dur)        return 0;    return totalBytes() * maxTime / dur;}bool MediaPlayerPrivate::totalBytesKnown() const{    return totalBytes() > 0;}unsigned MediaPlayerPrivate::totalBytes() const{    if (!m_qtMovie)        return 0;    return m_qtMovie->dataSize();}void MediaPlayerPrivate::cancelLoad(){    if (m_networkState < MediaPlayer::Loading || m_networkState == MediaPlayer::Loaded)        return;        // Cancel the load by destroying the movie.    m_qtMovie.clear();        updateStates();}void MediaPlayerPrivate::updateStates(){    MediaPlayer::NetworkState oldNetworkState = m_networkState;    MediaPlayer::ReadyState oldReadyState = m_readyState;      long loadState = m_qtMovie ? m_qtMovie->loadState() : QTMovieLoadStateError;    if (loadState >= QTMovieLoadStateLoaded && m_networkState < MediaPlayer::LoadedMetaData && !m_player->inMediaDocument()) {        unsigned enabledTrackCount;        m_qtMovie->disableUnsupportedTracks(enabledTrackCount);        // FIXME: We should differentiate between load errors and decode errors <rdar://problem/5605692>        if (!enabledTrackCount)            loadState = QTMovieLoadStateError;    }    // "Loaded" is reserved for fully buffered movies, never the case when streaming    if (loadState >= QTMovieLoadStateComplete && !m_isStreaming) {        if (m_networkState < MediaPlayer::Loaded)            m_networkState = MediaPlayer::Loaded;        m_readyState = MediaPlayer::CanPlayThrough;    } else if (loadState >= QTMovieLoadStatePlaythroughOK) {        if (m_networkState < MediaPlayer::LoadedFirstFrame && !seeking())            m_networkState = MediaPlayer::LoadedFirstFrame;        m_readyState = MediaPlayer::CanPlayThrough;    } else if (loadState >= QTMovieLoadStatePlayable) {        if (m_networkState < MediaPlayer::LoadedFirstFrame && !seeking())            m_networkState = MediaPlayer::LoadedFirstFrame;        m_readyState = currentTime() < maxTimeLoaded() ? MediaPlayer::CanPlay : MediaPlayer::DataUnavailable;    } else if (loadState >= QTMovieLoadStateLoaded) {        if (m_networkState < MediaPlayer::LoadedMetaData)            m_networkState = MediaPlayer::LoadedMetaData;        m_readyState = MediaPlayer::DataUnavailable;    } else if (loadState > QTMovieLoadStateError) {        if (m_networkState < MediaPlayer::Loading)            m_networkState = MediaPlayer::Loading;        m_readyState = MediaPlayer::DataUnavailable;            } else {        m_networkState = MediaPlayer::LoadFailed;        m_readyState = MediaPlayer::DataUnavailable;     }    if (seeking())        m_readyState = MediaPlayer::DataUnavailable;        if (m_networkState != oldNetworkState)        m_player->networkStateChanged();    if (m_readyState != oldReadyState)        m_player->readyStateChanged();}void MediaPlayerPrivate::didEnd(){    m_endPointTimer.stop();    m_startedPlaying = false;#if DRAW_FRAME_RATE    m_timeStoppedPlaying = GetTickCount();#endif    updateStates();    m_player->timeChanged();}void MediaPlayerPrivate::setSize(const IntSize& size) {     if (m_qtMovie)        m_qtMovie->setSize(size.width(), size.height());}void MediaPlayerPrivate::setVisible(bool b){    if (!m_qtMovie)        return;    m_qtMovie->setVisible(b);}void MediaPlayerPrivate::paint(GraphicsContext* p, const IntRect& r){    if (p->paintingDisabled() || !m_qtMovie)        return;    HDC hdc = p->getWindowsContext(r);    m_qtMovie->paint(hdc, r.x(), r.y());    p->releaseWindowsContext(hdc, r);#if DRAW_FRAME_RATE    if (m_frameCountWhilePlaying > 10) {        Frame* frame = m_player->frameView() ? m_player->frameView()->frame() : NULL;        Document* document = frame ? frame->document() : NULL;        RenderObject* renderer = document ? document->renderer() : NULL;        RenderStyle* styleToUse = renderer ? renderer->style() : NULL;        if (styleToUse) {            double frameRate = (m_frameCountWhilePlaying - 1) / (0.001 * ( m_startedPlaying ? (GetTickCount() - m_timeStartedPlaying) :                (m_timeStoppedPlaying - m_timeStartedPlaying) ));            String text = String::format("%1.2f", frameRate);            TextRun textRun(text.characters(), text.length());            const Color color(255, 0, 0);            p->save();            p->translate(r.x(), r.y() + r.height());            p->setFont(styleToUse->font());            p->setStrokeColor(color);            p->setStrokeStyle(SolidStroke);            p->setStrokeThickness(1.0f);            p->setFillColor(color);            p->drawText(textRun, IntPoint(2, -3));            p->restore();        }    }#endif}static HashSet<String> mimeTypeCache(){    DEFINE_STATIC_LOCAL(HashSet<String>, typeCache, ());    static bool typeListInitialized = false;    if (!typeListInitialized) {        unsigned count = QTMovieWin::countSupportedTypes();        for (unsigned n = 0; n < count; n++) {            const UChar* character;            unsigned len;            QTMovieWin::getSupportedType(n, character, len);            if (len)                typeCache.add(String(character, len));        }        typeListInitialized = true;    }        return typeCache;} void MediaPlayerPrivate::getSupportedTypes(HashSet<String>& types){    types = mimeTypeCache();} bool MediaPlayerPrivate::isAvailable(){    return QTMovieWin::initializeQuickTime();}MediaPlayer::SupportsType MediaPlayerPrivate::supportsType(const String& type, const String& codecs){    // only return "IsSupported" if there is no codecs parameter for now as there is no way to ask QT if it supports an    //  extended MIME type    return mimeTypeCache().contains(type) ? (!codecs.isEmpty() ? MediaPlayer::MayBeSupported : MediaPlayer::IsSupported) : MediaPlayer::IsNotSupported;}void MediaPlayerPrivate::movieEnded(QTMovieWin* movie){    ASSERT(m_qtMovie.get() == movie);    didEnd();}void MediaPlayerPrivate::movieLoadStateChanged(QTMovieWin* movie){    ASSERT(m_qtMovie.get() == movie);    updateStates();}void MediaPlayerPrivate::movieTimeChanged(QTMovieWin* movie){    ASSERT(m_qtMovie.get() == movie);    updateStates();    m_player->timeChanged();}void MediaPlayerPrivate::movieNewImageAvailable(QTMovieWin* movie){    ASSERT(m_qtMovie.get() == movie);#if DRAW_FRAME_RATE    if (m_startedPlaying) {        m_frameCountWhilePlaying++;        // to eliminate preroll costs from our calculation,        // our frame rate calculation excludes the first frame drawn after playback starts        if (1==m_frameCountWhilePlaying)            m_timeStartedPlaying = GetTickCount();    }#endif    m_player->repaint();}}#endif

⌨️ 快捷键说明

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