set eol-style to native on tons of files to head off future mixed-line-ending problems
[WebKit-https.git] / WebCore / platform / graphics / win / MediaPlayerPrivateQuickTimeWin.cpp
index 0480689..9ab6428 100644 (file)
-/*\r
- * Copyright (C) 2007 Apple Inc. All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions\r
- * are met:\r
- * 1. Redistributions of source code must retain the above copyright\r
- *    notice, this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright\r
- *    notice, this list of conditions and the following disclaimer in the\r
- *    documentation and/or other materials provided with the distribution.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY\r
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR\r
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\r
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \r
- */\r
-\r
-#include "config.h"\r
-\r
-#if ENABLE(VIDEO)\r
-#include "MediaPlayerPrivateQuickTimeWin.h"\r
-\r
-#include "DeprecatedString.h"\r
-#include "GraphicsContext.h"\r
-#include "KURL.h"\r
-#include "QTMovieWin.h"\r
-#include "ScrollView.h"\r
-#include <wtf/MathExtras.h>\r
-\r
-using namespace std;\r
-\r
-namespace WebCore {\r
-\r
-static const double endPointTimerInterval = 0.020;\r
-    \r
-MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)\r
-    : m_player(player)\r
-    , m_seekTo(-1)\r
-    , m_endTime(numeric_limits<float>::infinity())\r
-    , m_seekTimer(this, &MediaPlayerPrivate::seekTimerFired)\r
-    , m_endPointTimer(this, &MediaPlayerPrivate::endPointTimerFired)\r
-    , m_networkState(MediaPlayer::Empty)\r
-    , m_readyState(MediaPlayer::DataUnavailable)\r
-    , m_startedPlaying(false)\r
-    , m_isStreaming(false)\r
-{\r
-}\r
-\r
-MediaPlayerPrivate::~MediaPlayerPrivate()\r
-{\r
-}\r
-\r
-void MediaPlayerPrivate::load(const String& url)\r
-{\r
-    if (!QTMovieWin::initializeQuickTime()) {\r
-        m_networkState = MediaPlayer::LoadFailed;\r
-        m_player->networkStateChanged();\r
-        return;\r
-    }\r
-\r
-    if (m_networkState != MediaPlayer::Loading) {\r
-        m_networkState = MediaPlayer::Loading;\r
-        m_player->networkStateChanged();\r
-    }\r
-    if (m_readyState != MediaPlayer::DataUnavailable) {\r
-        m_readyState = MediaPlayer::DataUnavailable;\r
-        m_player->readyStateChanged();\r
-    }\r
-    cancelSeek();\r
-    m_endPointTimer.stop();\r
-\r
-    m_qtMovie.set(new QTMovieWin(this));\r
-    m_qtMovie->load(url.characters(), url.length());\r
-    m_qtMovie->setMuted(m_player->m_muted);\r
-    m_qtMovie->setVolume(m_player->m_volume);\r
-    m_qtMovie->setVisible(m_player->m_visible);\r
-}\r
-\r
-void MediaPlayerPrivate::play()\r
-{\r
-    if (!m_qtMovie)\r
-        return;\r
-    m_startedPlaying = true;\r
-\r
-    m_qtMovie->play();\r
-    startEndPointTimerIfNeeded();\r
-}\r
-\r
-void MediaPlayerPrivate::pause()\r
-{\r
-    if (!m_qtMovie)\r
-        return;\r
-    m_startedPlaying = false;\r
-    m_qtMovie->pause();\r
-    m_endPointTimer.stop();\r
-}\r
-\r
-float MediaPlayerPrivate::duration() const\r
-{\r
-    if (!m_qtMovie)\r
-        return 0;\r
-    return m_qtMovie->duration();\r
-}\r
-\r
-float MediaPlayerPrivate::currentTime() const\r
-{\r
-    if (!m_qtMovie)\r
-        return 0;\r
-    return min(m_qtMovie->currentTime(), m_endTime);\r
-}\r
-\r
-void MediaPlayerPrivate::seek(float time)\r
-{\r
-    cancelSeek();\r
-    \r
-    if (!m_qtMovie)\r
-        return;\r
-    \r
-    if (time > duration())\r
-        time = duration();\r
-    \r
-    m_seekTo = time;\r
-    if (maxTimeLoaded() >= m_seekTo)\r
-        doSeek();\r
-    else \r
-        m_seekTimer.start(0, 0.5f);\r
-}\r
-    \r
-void MediaPlayerPrivate::doSeek() \r
-{\r
-    float oldRate = m_qtMovie->rate();\r
-    m_qtMovie->setRate(0);\r
-    m_qtMovie->setCurrentTime(m_seekTo);\r
-    float timeAfterSeek = currentTime();\r
-    // restore playback only if not at end, othewise QTMovie will loop\r
-    if (timeAfterSeek < duration() && timeAfterSeek < m_endTime)\r
-        m_qtMovie->setRate(oldRate);\r
-    cancelSeek();\r
-}\r
-\r
-void MediaPlayerPrivate::cancelSeek()\r
-{\r
-    m_seekTo = -1;\r
-    m_seekTimer.stop();\r
-}\r
-\r
-void MediaPlayerPrivate::seekTimerFired(Timer<MediaPlayerPrivate>*)\r
-{        \r
-    if (!m_qtMovie || !seeking() || currentTime() == m_seekTo) {\r
-        cancelSeek();\r
-        updateStates();\r
-        m_player->timeChanged(); \r
-        return;\r
-    } \r
-    \r
-    if (maxTimeLoaded() >= m_seekTo)\r
-        doSeek();\r
-    else {\r
-        MediaPlayer::NetworkState state = networkState();\r
-        if (state == MediaPlayer::Empty || state == MediaPlayer::Loaded) {\r
-            cancelSeek();\r
-            updateStates();\r
-            m_player->timeChanged();\r
-        }\r
-    }\r
-}\r
-\r
-void MediaPlayerPrivate::setEndTime(float time)\r
-{\r
-    m_endTime = time;\r
-    startEndPointTimerIfNeeded();\r
-}\r
-\r
-void MediaPlayerPrivate::startEndPointTimerIfNeeded()\r
-{\r
-    if (m_endTime < duration() && m_startedPlaying && !m_endPointTimer.isActive())\r
-        m_endPointTimer.startRepeating(endPointTimerInterval);\r
-}\r
-\r
-void MediaPlayerPrivate::endPointTimerFired(Timer<MediaPlayerPrivate>*)\r
-{\r
-    float time = currentTime();\r
-    if (time >= m_endTime) {\r
-        pause();\r
-        didEnd();\r
-    }\r
-}\r
-\r
-bool MediaPlayerPrivate::paused() const\r
-{\r
-    if (!m_qtMovie)\r
-        return true;\r
-    return m_qtMovie->rate() == 0.0f;\r
-}\r
-\r
-bool MediaPlayerPrivate::seeking() const\r
-{\r
-    if (!m_qtMovie)\r
-        return false;\r
-    return m_seekTo >= 0;\r
-}\r
-\r
-IntSize MediaPlayerPrivate::naturalSize() const\r
-{\r
-    if (!m_qtMovie)\r
-        return IntSize();\r
-    int width;\r
-    int height;\r
-    m_qtMovie->getNaturalSize(width, height);\r
-    return IntSize(width, height);\r
-}\r
-\r
-bool MediaPlayerPrivate::hasVideo() const\r
-{\r
-    // This is not used at the moment\r
-    return true;\r
-}\r
-\r
-void MediaPlayerPrivate::setVolume(float volume)\r
-{\r
-    if (!m_qtMovie)\r
-        return;\r
-    m_qtMovie->setVolume(volume);\r
-}\r
-\r
-void MediaPlayerPrivate::setMuted(bool b)\r
-{\r
-    if (!m_qtMovie)\r
-        return;\r
-    m_qtMovie->setMuted(b);\r
-}\r
-\r
-void MediaPlayerPrivate::setRate(float rate)\r
-{\r
-    if (!m_qtMovie)\r
-        return;\r
-    if (!paused())\r
-        m_qtMovie->setRate(rate);\r
-}\r
-\r
-int MediaPlayerPrivate::dataRate() const\r
-{\r
-    // This is not used at the moment\r
-    return 0;\r
-}\r
-\r
-float MediaPlayerPrivate::maxTimeBuffered() const\r
-{\r
-    // rtsp streams are not buffered\r
-    return m_isStreaming ? 0 : maxTimeLoaded();\r
-}\r
-\r
-float MediaPlayerPrivate::maxTimeSeekable() const\r
-{\r
-    // infinite duration means live stream\r
-    return !isfinite(duration()) ? 0 : maxTimeLoaded();\r
-}\r
-\r
-float MediaPlayerPrivate::maxTimeLoaded() const\r
-{\r
-    if (!m_qtMovie)\r
-        return 0;\r
-    return m_qtMovie->maxTimeLoaded(); \r
-}\r
-\r
-unsigned MediaPlayerPrivate::bytesLoaded() const\r
-{\r
-    if (!m_qtMovie)\r
-        return 0;\r
-    float dur = duration();\r
-    float maxTime = maxTimeLoaded();\r
-    if (!dur)\r
-        return 0;\r
-    return totalBytes() * maxTime / dur;\r
-}\r
-\r
-bool MediaPlayerPrivate::totalBytesKnown() const\r
-{\r
-    return totalBytes() > 0;\r
-}\r
-\r
-unsigned MediaPlayerPrivate::totalBytes() const\r
-{\r
-    if (!m_qtMovie)\r
-        return 0;\r
-    return m_qtMovie->dataSize();\r
-}\r
-\r
-void MediaPlayerPrivate::cancelLoad()\r
-{\r
-    if (m_networkState < MediaPlayer::Loading || m_networkState == MediaPlayer::Loaded)\r
-        return;\r
-    \r
-    // Cancel the load by destroying the movie.\r
-    m_qtMovie.clear();\r
-    \r
-    updateStates();\r
-}\r
-\r
-void MediaPlayerPrivate::updateStates()\r
-{\r
-    MediaPlayer::NetworkState oldNetworkState = m_networkState;\r
-    MediaPlayer::ReadyState oldReadyState = m_readyState;\r
-  \r
-    long loadState = m_qtMovie ? m_qtMovie->loadState() : QTMovieLoadStateError;\r
-\r
-    if (loadState >= QTMovieLoadStateLoaded && m_networkState < MediaPlayer::LoadedMetaData) {\r
-        unsigned enabledTrackCount;\r
-        m_qtMovie->disableUnsupportedTracks(enabledTrackCount);\r
-        // FIXME: We should differentiate between load errors and decode errors <rdar://problem/5605692>\r
-        if (!enabledTrackCount)\r
-            loadState = QTMovieLoadStateError;\r
-    }\r
-\r
-    // "Loaded" is reserved for fully buffered movies, never the case when streaming\r
-    if (loadState >= QTMovieLoadStateComplete && !m_isStreaming) {\r
-        if (m_networkState < MediaPlayer::Loaded)\r
-            m_networkState = MediaPlayer::Loaded;\r
-        m_readyState = MediaPlayer::CanPlayThrough;\r
-    } else if (loadState >= QTMovieLoadStatePlaythroughOK) {\r
-        if (m_networkState < MediaPlayer::LoadedFirstFrame && !seeking())\r
-            m_networkState = MediaPlayer::LoadedFirstFrame;\r
-        m_readyState = (m_qtMovie->rate() == 0.0f && m_startedPlaying) ? MediaPlayer::DataUnavailable : MediaPlayer::CanPlayThrough;\r
-    } else if (loadState >= QTMovieLoadStatePlayable) {\r
-        if (m_networkState < MediaPlayer::LoadedFirstFrame && !seeking())\r
-            m_networkState = MediaPlayer::LoadedFirstFrame;\r
-        m_readyState = (m_qtMovie->rate() == 0.0f && m_startedPlaying) ? MediaPlayer::DataUnavailable : MediaPlayer::CanPlay;\r
-    } else if (loadState >= QTMovieLoadStateLoaded) {\r
-        if (m_networkState < MediaPlayer::LoadedMetaData)\r
-            m_networkState = MediaPlayer::LoadedMetaData;\r
-        m_readyState = MediaPlayer::DataUnavailable;\r
-    } else if (loadState > QTMovieLoadStateError) {\r
-        if (m_networkState < MediaPlayer::Loading)\r
-            m_networkState = MediaPlayer::Loading;\r
-        m_readyState = MediaPlayer::DataUnavailable;        \r
-    } else {\r
-        m_networkState = MediaPlayer::LoadFailed;\r
-        m_readyState = MediaPlayer::DataUnavailable; \r
-    }\r
-\r
-    if (seeking())\r
-        m_readyState = MediaPlayer::DataUnavailable;\r
-    \r
-    if (m_networkState != oldNetworkState)\r
-        m_player->networkStateChanged();\r
-    if (m_readyState != oldReadyState)\r
-        m_player->readyStateChanged();\r
-}\r
-\r
-\r
-void MediaPlayerPrivate::didEnd()\r
-{\r
-    m_endPointTimer.stop();\r
-    m_startedPlaying = false;\r
-    updateStates();\r
-    m_player->timeChanged();\r
-}\r
-\r
-void MediaPlayerPrivate::setRect(const IntRect& r) \r
-{ \r
-    if (m_qtMovie)\r
-        m_qtMovie->setSize(r.width(), r.height());\r
-}\r
-\r
-void MediaPlayerPrivate::setVisible(bool b)\r
-{\r
-    if (!m_qtMovie)\r
-        return;\r
-    m_qtMovie->setVisible(b);\r
-}\r
-\r
-void MediaPlayerPrivate::paint(GraphicsContext* p, const IntRect& r)\r
-{\r
-    if (p->paintingDisabled() || !m_qtMovie)\r
-        return;\r
-    HDC hdc = p->getWindowsContext(r);\r
-    m_qtMovie->paint(hdc, r.x(), r.y());\r
-    p->releaseWindowsContext(hdc, r);\r
-}\r
-\r
-void MediaPlayerPrivate::getSupportedTypes(HashSet<String>& types)\r
-{\r
-    unsigned count = QTMovieWin::countSupportedTypes();\r
-    for (unsigned n = 0; n < count; n++) {\r
-        const UChar* character;\r
-        unsigned len;\r
-        QTMovieWin::getSupportedType(n, character, len);\r
-        if (len)\r
-            types.add(String(character, len));\r
-    }\r
-} \r
-\r
-bool MediaPlayerPrivate::isAvailable()\r
-{\r
-    return QTMovieWin::initializeQuickTime();\r
-}\r
-\r
-void MediaPlayerPrivate::movieEnded(QTMovieWin* movie)\r
-{\r
-    ASSERT(m_qtMovie.get() == movie);\r
-    didEnd();\r
-}\r
-\r
-void MediaPlayerPrivate::movieLoadStateChanged(QTMovieWin* movie)\r
-{\r
-    ASSERT(m_qtMovie.get() == movie);\r
-    updateStates();\r
-}\r
-\r
-void MediaPlayerPrivate::movieTimeChanged(QTMovieWin* movie)\r
-{\r
-    ASSERT(m_qtMovie.get() == movie);\r
-    updateStates();\r
-    m_player->timeChanged();\r
-}\r
-\r
-void MediaPlayerPrivate::movieNewImageAvailable(QTMovieWin* movie)\r
-{\r
-    ASSERT(m_qtMovie.get() == movie);\r
-    m_player->repaint();\r
-}\r
-\r
-}\r
-\r
-#endif\r
-\r
+/*
+ * Copyright (C) 2007 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 "DeprecatedString.h"
+#include "GraphicsContext.h"
+#include "KURL.h"
+#include "QTMovieWin.h"
+#include "ScrollView.h"
+#include <wtf/MathExtras.h>
+
+using namespace std;
+
+namespace WebCore {
+
+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)
+{
+}
+
+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->setMuted(m_player->m_muted);
+    m_qtMovie->setVolume(m_player->m_volume);
+    m_qtMovie->setVisible(m_player->m_visible);
+}
+
+void MediaPlayerPrivate::play()
+{
+    if (!m_qtMovie)
+        return;
+    m_startedPlaying = true;
+
+    m_qtMovie->play();
+    startEndPointTimerIfNeeded();
+}
+
+void MediaPlayerPrivate::pause()
+{
+    if (!m_qtMovie)
+        return;
+    m_startedPlaying = false;
+    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
+{
+    // This is not used at the moment
+    return true;
+}
+
+void MediaPlayerPrivate::setVolume(float volume)
+{
+    if (!m_qtMovie)
+        return;
+    m_qtMovie->setVolume(volume);
+}
+
+void MediaPlayerPrivate::setMuted(bool b)
+{
+    if (!m_qtMovie)
+        return;
+    m_qtMovie->setMuted(b);
+}
+
+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) {
+        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 = (m_qtMovie->rate() == 0.0f && m_startedPlaying) ? MediaPlayer::DataUnavailable : MediaPlayer::CanPlayThrough;
+    } else if (loadState >= QTMovieLoadStatePlayable) {
+        if (m_networkState < MediaPlayer::LoadedFirstFrame && !seeking())
+            m_networkState = MediaPlayer::LoadedFirstFrame;
+        m_readyState = (m_qtMovie->rate() == 0.0f && m_startedPlaying) ? MediaPlayer::DataUnavailable : MediaPlayer::CanPlay;
+    } 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;
+    updateStates();
+    m_player->timeChanged();
+}
+
+void MediaPlayerPrivate::setRect(const IntRect& r) 
+{ 
+    if (m_qtMovie)
+        m_qtMovie->setSize(r.width(), r.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);
+}
+
+void MediaPlayerPrivate::getSupportedTypes(HashSet<String>& types)
+{
+    unsigned count = QTMovieWin::countSupportedTypes();
+    for (unsigned n = 0; n < count; n++) {
+        const UChar* character;
+        unsigned len;
+        QTMovieWin::getSupportedType(n, character, len);
+        if (len)
+            types.add(String(character, len));
+    }
+} 
+
+bool MediaPlayerPrivate::isAvailable()
+{
+    return QTMovieWin::initializeQuickTime();
+}
+
+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);
+    m_player->repaint();
+}
+
+}
+
+#endif
+