1/*
2 * Copyright (C) 2013-2018 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 "MockMediaSourcePrivate.h"
28
29#if ENABLE(MEDIA_SOURCE)
30
31#include "ContentType.h"
32#include "MediaSourcePrivateClient.h"
33#include "MockMediaPlayerMediaSource.h"
34#include "MockSourceBufferPrivate.h"
35
36namespace WebCore {
37
38Ref<MockMediaSourcePrivate> MockMediaSourcePrivate::create(MockMediaPlayerMediaSource& parent, MediaSourcePrivateClient& client)
39{
40 auto source = adoptRef(*new MockMediaSourcePrivate(parent, client));
41 client.setPrivateAndOpen(source.copyRef());
42 return source;
43}
44
45MockMediaSourcePrivate::MockMediaSourcePrivate(MockMediaPlayerMediaSource& parent, MediaSourcePrivateClient& client)
46 : m_player(parent)
47 , m_client(client)
48{
49#if !RELEASE_LOG_DISABLED
50 m_client->setLogIdentifier(m_player.mediaPlayerLogIdentifier());
51#endif
52}
53
54MockMediaSourcePrivate::~MockMediaSourcePrivate()
55{
56 for (auto& buffer : m_sourceBuffers)
57 buffer->clearMediaSource();
58}
59
60MediaSourcePrivate::AddStatus MockMediaSourcePrivate::addSourceBuffer(const ContentType& contentType, RefPtr<SourceBufferPrivate>& outPrivate)
61{
62 MediaEngineSupportParameters parameters;
63 parameters.isMediaSource = true;
64 parameters.type = contentType;
65 if (MockMediaPlayerMediaSource::supportsType(parameters) == MediaPlayer::IsNotSupported)
66 return NotSupported;
67
68 m_sourceBuffers.append(MockSourceBufferPrivate::create(this));
69 outPrivate = m_sourceBuffers.last();
70
71 return Ok;
72}
73
74void MockMediaSourcePrivate::removeSourceBuffer(SourceBufferPrivate* buffer)
75{
76 ASSERT(m_sourceBuffers.contains(buffer));
77 m_activeSourceBuffers.removeFirst(buffer);
78 m_sourceBuffers.removeFirst(buffer);
79}
80
81MediaTime MockMediaSourcePrivate::duration()
82{
83 return m_client->duration();
84}
85
86std::unique_ptr<PlatformTimeRanges> MockMediaSourcePrivate::buffered()
87{
88 return m_client->buffered();
89}
90
91void MockMediaSourcePrivate::durationChanged()
92{
93 m_player.updateDuration(duration());
94}
95
96void MockMediaSourcePrivate::markEndOfStream(EndOfStreamStatus status)
97{
98 if (status == EosNoError)
99 m_player.setNetworkState(MediaPlayer::Loaded);
100 m_isEnded = true;
101}
102
103void MockMediaSourcePrivate::unmarkEndOfStream()
104{
105 m_isEnded = false;
106}
107
108MediaPlayer::ReadyState MockMediaSourcePrivate::readyState() const
109{
110 return m_player.readyState();
111}
112
113void MockMediaSourcePrivate::setReadyState(MediaPlayer::ReadyState readyState)
114{
115 m_player.setReadyState(readyState);
116}
117
118void MockMediaSourcePrivate::waitForSeekCompleted()
119{
120 m_player.waitForSeekCompleted();
121}
122
123void MockMediaSourcePrivate::seekCompleted()
124{
125 m_player.seekCompleted();
126}
127
128void MockMediaSourcePrivate::sourceBufferPrivateDidChangeActiveState(MockSourceBufferPrivate* buffer, bool active)
129{
130 if (active && !m_activeSourceBuffers.contains(buffer))
131 m_activeSourceBuffers.append(buffer);
132
133 if (!active)
134 m_activeSourceBuffers.removeFirst(buffer);
135}
136
137static bool MockSourceBufferPrivateHasAudio(MockSourceBufferPrivate* sourceBuffer)
138{
139 return sourceBuffer->hasAudio();
140}
141
142bool MockMediaSourcePrivate::hasAudio() const
143{
144 return std::any_of(m_activeSourceBuffers.begin(), m_activeSourceBuffers.end(), MockSourceBufferPrivateHasAudio);
145}
146
147static bool MockSourceBufferPrivateHasVideo(MockSourceBufferPrivate* sourceBuffer)
148{
149 return sourceBuffer->hasVideo();
150}
151
152bool MockMediaSourcePrivate::hasVideo() const
153{
154 return std::any_of(m_activeSourceBuffers.begin(), m_activeSourceBuffers.end(), MockSourceBufferPrivateHasVideo);
155}
156
157void MockMediaSourcePrivate::seekToTime(const MediaTime& time)
158{
159 m_client->seekToTime(time);
160}
161
162MediaTime MockMediaSourcePrivate::seekToTime(const MediaTime& targetTime, const MediaTime& negativeThreshold, const MediaTime& positiveThreshold)
163{
164 MediaTime seekTime = targetTime;
165 for (auto& buffer : m_activeSourceBuffers) {
166 MediaTime sourceSeekTime = buffer->fastSeekTimeForMediaTime(targetTime, negativeThreshold, positiveThreshold);
167 if (abs(targetTime - sourceSeekTime) > abs(targetTime - seekTime))
168 seekTime = sourceSeekTime;
169 }
170
171 return seekTime;
172}
173
174Optional<VideoPlaybackQualityMetrics> MockMediaSourcePrivate::videoPlaybackQualityMetrics()
175{
176 return VideoPlaybackQualityMetrics {
177 m_totalVideoFrames,
178 m_droppedVideoFrames,
179 m_corruptedVideoFrames,
180 m_totalFrameDelay.toDouble(),
181 0,
182 };
183}
184
185#if !RELEASE_LOG_DISABLED
186const Logger& MockMediaSourcePrivate::mediaSourceLogger() const
187{
188 return m_player.mediaPlayerLogger();
189}
190
191const void* MockMediaSourcePrivate::mediaSourceLogIdentifier()
192{
193 return m_player.mediaPlayerLogIdentifier();
194}
195#endif
196
197}
198
199#endif
200