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
1 /*
2  * Copyright (C) 2007 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27
28 #if ENABLE(VIDEO)
29 #include "MediaPlayerPrivateQuickTimeWin.h"
30
31 #include "DeprecatedString.h"
32 #include "GraphicsContext.h"
33 #include "KURL.h"
34 #include "QTMovieWin.h"
35 #include "ScrollView.h"
36 #include <wtf/MathExtras.h>
37
38 using namespace std;
39
40 namespace WebCore {
41
42 static const double endPointTimerInterval = 0.020;
43     
44 MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
45     : m_player(player)
46     , m_seekTo(-1)
47     , m_endTime(numeric_limits<float>::infinity())
48     , m_seekTimer(this, &MediaPlayerPrivate::seekTimerFired)
49     , m_endPointTimer(this, &MediaPlayerPrivate::endPointTimerFired)
50     , m_networkState(MediaPlayer::Empty)
51     , m_readyState(MediaPlayer::DataUnavailable)
52     , m_startedPlaying(false)
53     , m_isStreaming(false)
54 {
55 }
56
57 MediaPlayerPrivate::~MediaPlayerPrivate()
58 {
59 }
60
61 void MediaPlayerPrivate::load(const String& url)
62 {
63     if (!QTMovieWin::initializeQuickTime()) {
64         m_networkState = MediaPlayer::LoadFailed;
65         m_player->networkStateChanged();
66         return;
67     }
68
69     if (m_networkState != MediaPlayer::Loading) {
70         m_networkState = MediaPlayer::Loading;
71         m_player->networkStateChanged();
72     }
73     if (m_readyState != MediaPlayer::DataUnavailable) {
74         m_readyState = MediaPlayer::DataUnavailable;
75         m_player->readyStateChanged();
76     }
77     cancelSeek();
78     m_endPointTimer.stop();
79
80     m_qtMovie.set(new QTMovieWin(this));
81     m_qtMovie->load(url.characters(), url.length());
82     m_qtMovie->setMuted(m_player->m_muted);
83     m_qtMovie->setVolume(m_player->m_volume);
84     m_qtMovie->setVisible(m_player->m_visible);
85 }
86
87 void MediaPlayerPrivate::play()
88 {
89     if (!m_qtMovie)
90         return;
91     m_startedPlaying = true;
92
93     m_qtMovie->play();
94     startEndPointTimerIfNeeded();
95 }
96
97 void MediaPlayerPrivate::pause()
98 {
99     if (!m_qtMovie)
100         return;
101     m_startedPlaying = false;
102     m_qtMovie->pause();
103     m_endPointTimer.stop();
104 }
105
106 float MediaPlayerPrivate::duration() const
107 {
108     if (!m_qtMovie)
109         return 0;
110     return m_qtMovie->duration();
111 }
112
113 float MediaPlayerPrivate::currentTime() const
114 {
115     if (!m_qtMovie)
116         return 0;
117     return min(m_qtMovie->currentTime(), m_endTime);
118 }
119
120 void MediaPlayerPrivate::seek(float time)
121 {
122     cancelSeek();
123     
124     if (!m_qtMovie)
125         return;
126     
127     if (time > duration())
128         time = duration();
129     
130     m_seekTo = time;
131     if (maxTimeLoaded() >= m_seekTo)
132         doSeek();
133     else 
134         m_seekTimer.start(0, 0.5f);
135 }
136     
137 void MediaPlayerPrivate::doSeek() 
138 {
139     float oldRate = m_qtMovie->rate();
140     m_qtMovie->setRate(0);
141     m_qtMovie->setCurrentTime(m_seekTo);
142     float timeAfterSeek = currentTime();
143     // restore playback only if not at end, othewise QTMovie will loop
144     if (timeAfterSeek < duration() && timeAfterSeek < m_endTime)
145         m_qtMovie->setRate(oldRate);
146     cancelSeek();
147 }
148
149 void MediaPlayerPrivate::cancelSeek()
150 {
151     m_seekTo = -1;
152     m_seekTimer.stop();
153 }
154
155 void MediaPlayerPrivate::seekTimerFired(Timer<MediaPlayerPrivate>*)
156 {        
157     if (!m_qtMovie || !seeking() || currentTime() == m_seekTo) {
158         cancelSeek();
159         updateStates();
160         m_player->timeChanged(); 
161         return;
162     } 
163     
164     if (maxTimeLoaded() >= m_seekTo)
165         doSeek();
166     else {
167         MediaPlayer::NetworkState state = networkState();
168         if (state == MediaPlayer::Empty || state == MediaPlayer::Loaded) {
169             cancelSeek();
170             updateStates();
171             m_player->timeChanged();
172         }
173     }
174 }
175
176 void MediaPlayerPrivate::setEndTime(float time)
177 {
178     m_endTime = time;
179     startEndPointTimerIfNeeded();
180 }
181
182 void MediaPlayerPrivate::startEndPointTimerIfNeeded()
183 {
184     if (m_endTime < duration() && m_startedPlaying && !m_endPointTimer.isActive())
185         m_endPointTimer.startRepeating(endPointTimerInterval);
186 }
187
188 void MediaPlayerPrivate::endPointTimerFired(Timer<MediaPlayerPrivate>*)
189 {
190     float time = currentTime();
191     if (time >= m_endTime) {
192         pause();
193         didEnd();
194     }
195 }
196
197 bool MediaPlayerPrivate::paused() const
198 {
199     if (!m_qtMovie)
200         return true;
201     return m_qtMovie->rate() == 0.0f;
202 }
203
204 bool MediaPlayerPrivate::seeking() const
205 {
206     if (!m_qtMovie)
207         return false;
208     return m_seekTo >= 0;
209 }
210
211 IntSize MediaPlayerPrivate::naturalSize() const
212 {
213     if (!m_qtMovie)
214         return IntSize();
215     int width;
216     int height;
217     m_qtMovie->getNaturalSize(width, height);
218     return IntSize(width, height);
219 }
220
221 bool MediaPlayerPrivate::hasVideo() const
222 {
223     // This is not used at the moment
224     return true;
225 }
226
227 void MediaPlayerPrivate::setVolume(float volume)
228 {
229     if (!m_qtMovie)
230         return;
231     m_qtMovie->setVolume(volume);
232 }
233
234 void MediaPlayerPrivate::setMuted(bool b)
235 {
236     if (!m_qtMovie)
237         return;
238     m_qtMovie->setMuted(b);
239 }
240
241 void MediaPlayerPrivate::setRate(float rate)
242 {
243     if (!m_qtMovie)
244         return;
245     if (!paused())
246         m_qtMovie->setRate(rate);
247 }
248
249 int MediaPlayerPrivate::dataRate() const
250 {
251     // This is not used at the moment
252     return 0;
253 }
254
255 float MediaPlayerPrivate::maxTimeBuffered() const
256 {
257     // rtsp streams are not buffered
258     return m_isStreaming ? 0 : maxTimeLoaded();
259 }
260
261 float MediaPlayerPrivate::maxTimeSeekable() const
262 {
263     // infinite duration means live stream
264     return !isfinite(duration()) ? 0 : maxTimeLoaded();
265 }
266
267 float MediaPlayerPrivate::maxTimeLoaded() const
268 {
269     if (!m_qtMovie)
270         return 0;
271     return m_qtMovie->maxTimeLoaded(); 
272 }
273
274 unsigned MediaPlayerPrivate::bytesLoaded() const
275 {
276     if (!m_qtMovie)
277         return 0;
278     float dur = duration();
279     float maxTime = maxTimeLoaded();
280     if (!dur)
281         return 0;
282     return totalBytes() * maxTime / dur;
283 }
284
285 bool MediaPlayerPrivate::totalBytesKnown() const
286 {
287     return totalBytes() > 0;
288 }
289
290 unsigned MediaPlayerPrivate::totalBytes() const
291 {
292     if (!m_qtMovie)
293         return 0;
294     return m_qtMovie->dataSize();
295 }
296
297 void MediaPlayerPrivate::cancelLoad()
298 {
299     if (m_networkState < MediaPlayer::Loading || m_networkState == MediaPlayer::Loaded)
300         return;
301     
302     // Cancel the load by destroying the movie.
303     m_qtMovie.clear();
304     
305     updateStates();
306 }
307
308 void MediaPlayerPrivate::updateStates()
309 {
310     MediaPlayer::NetworkState oldNetworkState = m_networkState;
311     MediaPlayer::ReadyState oldReadyState = m_readyState;
312   
313     long loadState = m_qtMovie ? m_qtMovie->loadState() : QTMovieLoadStateError;
314
315     if (loadState >= QTMovieLoadStateLoaded && m_networkState < MediaPlayer::LoadedMetaData) {
316         unsigned enabledTrackCount;
317         m_qtMovie->disableUnsupportedTracks(enabledTrackCount);
318         // FIXME: We should differentiate between load errors and decode errors <rdar://problem/5605692>
319         if (!enabledTrackCount)
320             loadState = QTMovieLoadStateError;
321     }
322
323     // "Loaded" is reserved for fully buffered movies, never the case when streaming
324     if (loadState >= QTMovieLoadStateComplete && !m_isStreaming) {
325         if (m_networkState < MediaPlayer::Loaded)
326             m_networkState = MediaPlayer::Loaded;
327         m_readyState = MediaPlayer::CanPlayThrough;
328     } else if (loadState >= QTMovieLoadStatePlaythroughOK) {
329         if (m_networkState < MediaPlayer::LoadedFirstFrame && !seeking())
330             m_networkState = MediaPlayer::LoadedFirstFrame;
331         m_readyState = (m_qtMovie->rate() == 0.0f && m_startedPlaying) ? MediaPlayer::DataUnavailable : MediaPlayer::CanPlayThrough;
332     } else if (loadState >= QTMovieLoadStatePlayable) {
333         if (m_networkState < MediaPlayer::LoadedFirstFrame && !seeking())
334             m_networkState = MediaPlayer::LoadedFirstFrame;
335         m_readyState = (m_qtMovie->rate() == 0.0f && m_startedPlaying) ? MediaPlayer::DataUnavailable : MediaPlayer::CanPlay;
336     } else if (loadState >= QTMovieLoadStateLoaded) {
337         if (m_networkState < MediaPlayer::LoadedMetaData)
338             m_networkState = MediaPlayer::LoadedMetaData;
339         m_readyState = MediaPlayer::DataUnavailable;
340     } else if (loadState > QTMovieLoadStateError) {
341         if (m_networkState < MediaPlayer::Loading)
342             m_networkState = MediaPlayer::Loading;
343         m_readyState = MediaPlayer::DataUnavailable;        
344     } else {
345         m_networkState = MediaPlayer::LoadFailed;
346         m_readyState = MediaPlayer::DataUnavailable; 
347     }
348
349     if (seeking())
350         m_readyState = MediaPlayer::DataUnavailable;
351     
352     if (m_networkState != oldNetworkState)
353         m_player->networkStateChanged();
354     if (m_readyState != oldReadyState)
355         m_player->readyStateChanged();
356 }
357
358
359 void MediaPlayerPrivate::didEnd()
360 {
361     m_endPointTimer.stop();
362     m_startedPlaying = false;
363     updateStates();
364     m_player->timeChanged();
365 }
366
367 void MediaPlayerPrivate::setRect(const IntRect& r) 
368
369     if (m_qtMovie)
370         m_qtMovie->setSize(r.width(), r.height());
371 }
372
373 void MediaPlayerPrivate::setVisible(bool b)
374 {
375     if (!m_qtMovie)
376         return;
377     m_qtMovie->setVisible(b);
378 }
379
380 void MediaPlayerPrivate::paint(GraphicsContext* p, const IntRect& r)
381 {
382     if (p->paintingDisabled() || !m_qtMovie)
383         return;
384     HDC hdc = p->getWindowsContext(r);
385     m_qtMovie->paint(hdc, r.x(), r.y());
386     p->releaseWindowsContext(hdc, r);
387 }
388
389 void MediaPlayerPrivate::getSupportedTypes(HashSet<String>& types)
390 {
391     unsigned count = QTMovieWin::countSupportedTypes();
392     for (unsigned n = 0; n < count; n++) {
393         const UChar* character;
394         unsigned len;
395         QTMovieWin::getSupportedType(n, character, len);
396         if (len)
397             types.add(String(character, len));
398     }
399
400
401 bool MediaPlayerPrivate::isAvailable()
402 {
403     return QTMovieWin::initializeQuickTime();
404 }
405
406 void MediaPlayerPrivate::movieEnded(QTMovieWin* movie)
407 {
408     ASSERT(m_qtMovie.get() == movie);
409     didEnd();
410 }
411
412 void MediaPlayerPrivate::movieLoadStateChanged(QTMovieWin* movie)
413 {
414     ASSERT(m_qtMovie.get() == movie);
415     updateStates();
416 }
417
418 void MediaPlayerPrivate::movieTimeChanged(QTMovieWin* movie)
419 {
420     ASSERT(m_qtMovie.get() == movie);
421     updateStates();
422     m_player->timeChanged();
423 }
424
425 void MediaPlayerPrivate::movieNewImageAvailable(QTMovieWin* movie)
426 {
427     ASSERT(m_qtMovie.get() == movie);
428     m_player->repaint();
429 }
430
431 }
432
433 #endif
434