1/*
2 * Copyright (C) 2013 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 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 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#include "MockMediaPlayerMediaSource.h"
28
29#if ENABLE(MEDIA_SOURCE)
30
31#include "ExceptionCodePlaceholder.h"
32#include "MediaPlayer.h"
33#include "MediaSourcePrivateClient.h"
34#include "MockMediaSourcePrivate.h"
35#include <wtf/Functional.h>
36#include <wtf/MainThread.h>
37#include <wtf/text/WTFString.h>
38
39namespace WebCore {
40
41// MediaPlayer Enigne Support
42void MockMediaPlayerMediaSource::registerMediaEngine(MediaEngineRegistrar registrar)
43{
44    registrar(create, getSupportedTypes, supportsType, 0, 0, 0, 0);
45}
46
47PassOwnPtr<MediaPlayerPrivateInterface> MockMediaPlayerMediaSource::create(MediaPlayer* player)
48{
49    return adoptPtr(new MockMediaPlayerMediaSource(player));
50}
51
52static HashSet<String> mimeTypeCache()
53{
54    DEPRECATED_DEFINE_STATIC_LOCAL(HashSet<String>, cache, ());
55    static bool isInitialized = false;
56
57    if (!isInitialized) {
58        isInitialized = true;
59        cache.add(ASCIILiteral("video/mock"));
60    }
61
62    return cache;
63}
64
65void MockMediaPlayerMediaSource::getSupportedTypes(HashSet<String>& supportedTypes)
66{
67    supportedTypes = mimeTypeCache();
68}
69
70MediaPlayer::SupportsType MockMediaPlayerMediaSource::supportsType(const MediaEngineSupportParameters& parameters)
71{
72    if (!parameters.isMediaSource)
73        return MediaPlayer::IsNotSupported;
74
75    if (!mimeTypeCache().contains(parameters.type))
76        return MediaPlayer::IsNotSupported;
77
78    if (parameters.codecs.isEmpty())
79        return MediaPlayer::MayBeSupported;
80
81    return parameters.codecs == "mock" ? MediaPlayer::IsSupported : MediaPlayer::MayBeSupported;
82}
83
84MockMediaPlayerMediaSource::MockMediaPlayerMediaSource(MediaPlayer* player)
85    : m_player(player)
86    , m_currentTime(MediaTime::zeroTime())
87    , m_readyState(MediaPlayer::HaveNothing)
88    , m_networkState(MediaPlayer::Empty)
89    , m_playing(false)
90    , m_seekCompleted(true)
91{
92}
93
94MockMediaPlayerMediaSource::~MockMediaPlayerMediaSource()
95{
96}
97
98void MockMediaPlayerMediaSource::load(const String&)
99{
100    ASSERT_NOT_REACHED();
101}
102
103void MockMediaPlayerMediaSource::load(const String&, MediaSourcePrivateClient* source)
104{
105    m_mediaSourcePrivate = MockMediaSourcePrivate::create(this, source);
106}
107
108void MockMediaPlayerMediaSource::cancelLoad()
109{
110}
111
112void MockMediaPlayerMediaSource::play()
113{
114    m_playing = 1;
115    callOnMainThread(bind(&MockMediaPlayerMediaSource::advanceCurrentTime, this));
116}
117
118void MockMediaPlayerMediaSource::pause()
119{
120    m_playing = 0;
121}
122
123IntSize MockMediaPlayerMediaSource::naturalSize() const
124{
125    return IntSize();
126}
127
128bool MockMediaPlayerMediaSource::hasVideo() const
129{
130    return m_mediaSourcePrivate ? m_mediaSourcePrivate->hasVideo() : false;
131}
132
133bool MockMediaPlayerMediaSource::hasAudio() const
134{
135    return m_mediaSourcePrivate ? m_mediaSourcePrivate->hasAudio() : false;
136}
137
138void MockMediaPlayerMediaSource::setVisible(bool)
139{
140}
141
142bool MockMediaPlayerMediaSource::seeking() const
143{
144    return !m_seekCompleted;
145}
146
147bool MockMediaPlayerMediaSource::paused() const
148{
149    return !m_playing;
150}
151
152MediaPlayer::NetworkState MockMediaPlayerMediaSource::networkState() const
153{
154    return m_networkState;
155}
156
157MediaPlayer::ReadyState MockMediaPlayerMediaSource::readyState() const
158{
159    return m_readyState;
160}
161
162double MockMediaPlayerMediaSource::maxTimeSeekableDouble() const
163{
164    return m_duration.toDouble();
165}
166
167std::unique_ptr<PlatformTimeRanges> MockMediaPlayerMediaSource::buffered() const
168{
169    if (m_mediaSourcePrivate)
170        return m_mediaSourcePrivate->buffered();
171
172    return PlatformTimeRanges::create();
173}
174
175bool MockMediaPlayerMediaSource::didLoadingProgress() const
176{
177    return false;
178}
179
180void MockMediaPlayerMediaSource::setSize(const IntSize&)
181{
182}
183
184void MockMediaPlayerMediaSource::paint(GraphicsContext*, const IntRect&)
185{
186}
187
188double MockMediaPlayerMediaSource::currentTimeDouble() const
189{
190    return m_currentTime.toDouble();
191}
192
193double MockMediaPlayerMediaSource::durationDouble() const
194{
195    return m_mediaSourcePrivate ? m_mediaSourcePrivate->duration() : 0;
196}
197
198void MockMediaPlayerMediaSource::seekWithTolerance(double time, double negativeTolerance, double positiveTolerance)
199{
200    if (!negativeTolerance && !positiveTolerance) {
201        m_currentTime = MediaTime::createWithDouble(time);
202        m_mediaSourcePrivate->seekToTime(MediaTime::createWithDouble(time));
203    } else
204        m_currentTime = m_mediaSourcePrivate->seekToTime(MediaTime::createWithDouble(time), MediaTime::createWithDouble(negativeTolerance), MediaTime::createWithDouble(positiveTolerance));
205
206    if (m_seekCompleted) {
207        m_player->timeChanged();
208
209        if (m_playing)
210            callOnMainThread(bind(&MockMediaPlayerMediaSource::advanceCurrentTime, this));
211    }
212}
213
214void MockMediaPlayerMediaSource::advanceCurrentTime()
215{
216    if (!m_mediaSourcePrivate)
217        return;
218
219    auto buffered = m_mediaSourcePrivate->buffered();
220    size_t pos = buffered->find(m_currentTime);
221    if (pos == notFound)
222        return;
223
224    bool ignoreError;
225    m_currentTime = std::min(m_duration, buffered->end(pos, ignoreError));
226    m_player->timeChanged();
227}
228
229void MockMediaPlayerMediaSource::updateDuration(const MediaTime& duration)
230{
231    if (m_duration == duration)
232        return;
233
234    m_duration = duration;
235    m_player->durationChanged();
236}
237
238void MockMediaPlayerMediaSource::setReadyState(MediaPlayer::ReadyState readyState)
239{
240    if (readyState == m_readyState)
241        return;
242
243    m_readyState = readyState;
244    m_player->readyStateChanged();
245}
246
247void MockMediaPlayerMediaSource::setNetworkState(MediaPlayer::NetworkState networkState)
248{
249    if (networkState == m_networkState)
250        return;
251
252    m_networkState = networkState;
253    m_player->networkStateChanged();
254}
255
256void MockMediaPlayerMediaSource::waitForSeekCompleted()
257{
258    m_seekCompleted = false;
259}
260
261void MockMediaPlayerMediaSource::seekCompleted()
262{
263    if (m_seekCompleted)
264        return;
265    m_seekCompleted = true;
266
267    m_player->timeChanged();
268
269    if (m_playing)
270        callOnMainThread(bind(&MockMediaPlayerMediaSource::advanceCurrentTime, this));
271}
272
273unsigned long MockMediaPlayerMediaSource::totalVideoFrames()
274{
275    return m_mediaSourcePrivate ? m_mediaSourcePrivate->totalVideoFrames() : 0;
276}
277
278unsigned long MockMediaPlayerMediaSource::droppedVideoFrames()
279{
280    return m_mediaSourcePrivate ? m_mediaSourcePrivate->droppedVideoFrames() : 0;
281}
282
283unsigned long MockMediaPlayerMediaSource::corruptedVideoFrames()
284{
285    return m_mediaSourcePrivate ? m_mediaSourcePrivate->corruptedVideoFrames() : 0;
286}
287
288double MockMediaPlayerMediaSource::totalFrameDelay()
289{
290    return m_mediaSourcePrivate ? m_mediaSourcePrivate->totalFrameDelay() : 0;
291}
292
293}
294
295#endif
296