Unreviewed, rolling out r234489.
[WebKit-https.git] / Source / WebCore / platform / mock / mediasource / MockSourceBufferPrivate.cpp
1 /*
2  * Copyright (C) 2013-2017 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 "MockSourceBufferPrivate.h"
28
29 #if ENABLE(MEDIA_SOURCE)
30
31 #include "MediaDescription.h"
32 #include "MediaPlayer.h"
33 #include "MediaSample.h"
34 #include "MockBox.h"
35 #include "MockMediaPlayerMediaSource.h"
36 #include "MockMediaSourcePrivate.h"
37 #include "MockTracks.h"
38 #include "SourceBufferPrivateClient.h"
39 #include <JavaScriptCore/ArrayBuffer.h>
40 #include <wtf/StringPrintStream.h>
41
42 namespace WebCore {
43
44 class MockMediaSample final : public MediaSample {
45 public:
46     static Ref<MockMediaSample> create(const MockSampleBox& box) { return adoptRef(*new MockMediaSample(box)); }
47     virtual ~MockMediaSample() = default;
48
49 private:
50     MockMediaSample(const MockSampleBox& box)
51         : m_box(box)
52         , m_id(String::format("%d", box.trackID()))
53     {
54     }
55
56     MediaTime presentationTime() const override { return m_box.presentationTimestamp(); }
57     MediaTime decodeTime() const override { return m_box.decodeTimestamp(); }
58     MediaTime duration() const override { return m_box.duration(); }
59     AtomicString trackID() const override { return m_id; }
60     void setTrackID(const String& id) override { m_id = id; }
61     size_t sizeInBytes() const override { return sizeof(m_box); }
62     SampleFlags flags() const override;
63     PlatformSample platformSample() override;
64     FloatSize presentationSize() const override { return FloatSize(); }
65     void dump(PrintStream&) const override;
66     void offsetTimestampsBy(const MediaTime& offset) override { m_box.offsetTimestampsBy(offset); }
67     void setTimestamps(const MediaTime& presentationTimestamp, const MediaTime& decodeTimestamp) override { m_box.setTimestamps(presentationTimestamp, decodeTimestamp); }
68     bool isDivisable() const override { return false; }
69     std::pair<RefPtr<MediaSample>, RefPtr<MediaSample>> divide(const MediaTime&) override { return {nullptr, nullptr}; }
70     Ref<MediaSample> createNonDisplayingCopy() const override;
71
72     unsigned generation() const { return m_box.generation(); }
73
74     MockSampleBox m_box;
75     AtomicString m_id;
76 };
77
78 MediaSample::SampleFlags MockMediaSample::flags() const
79 {
80     unsigned flags = None;
81     if (m_box.isSync())
82         flags |= IsSync;
83     if (m_box.isNonDisplaying())
84         flags |= IsNonDisplaying;
85     return SampleFlags(flags);
86 }
87
88 PlatformSample MockMediaSample::platformSample()
89 {
90     PlatformSample sample = { PlatformSample::MockSampleBoxType, { &m_box } };
91     return sample;
92 }
93
94 void MockMediaSample::dump(PrintStream& out) const
95 {
96     out.print("{PTS(", presentationTime(), "), DTS(", decodeTime(), "), duration(", duration(), "), flags(", (int)flags(), "), generation(", generation(), ")}");
97 }
98
99 Ref<MediaSample> MockMediaSample::createNonDisplayingCopy() const
100 {
101     auto copy = MockMediaSample::create(m_box);
102     copy->m_box.setFlag(MockSampleBox::IsNonDisplaying);
103     return WTFMove(copy);
104 }
105
106 class MockMediaDescription final : public MediaDescription {
107 public:
108     static RefPtr<MockMediaDescription> create(const MockTrackBox& box) { return adoptRef(new MockMediaDescription(box)); }
109     virtual ~MockMediaDescription() = default;
110
111     AtomicString codec() const override { return m_box.codec(); }
112     bool isVideo() const override { return m_box.kind() == MockTrackBox::Video; }
113     bool isAudio() const override { return m_box.kind() == MockTrackBox::Audio; }
114     bool isText() const override { return m_box.kind() == MockTrackBox::Text; }
115
116 protected:
117     MockMediaDescription(const MockTrackBox& box) : m_box(box) { }
118     MockTrackBox m_box;
119 };
120
121 RefPtr<MockSourceBufferPrivate> MockSourceBufferPrivate::create(MockMediaSourcePrivate* parent)
122 {
123     return adoptRef(new MockSourceBufferPrivate(parent));
124 }
125
126 MockSourceBufferPrivate::MockSourceBufferPrivate(MockMediaSourcePrivate* parent)
127     : m_mediaSource(parent)
128     , m_client(0)
129 {
130 }
131
132 MockSourceBufferPrivate::~MockSourceBufferPrivate() = default;
133
134 void MockSourceBufferPrivate::setClient(SourceBufferPrivateClient* client)
135 {
136     m_client = client;
137 }
138
139 void MockSourceBufferPrivate::append(Vector<unsigned char>&& data)
140 {
141     m_inputBuffer.appendVector(data);
142     SourceBufferPrivateClient::AppendResult result = SourceBufferPrivateClient::AppendSucceeded;
143
144     while (m_inputBuffer.size() && result == SourceBufferPrivateClient::AppendSucceeded) {
145         RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(m_inputBuffer.data(), m_inputBuffer.size());
146         size_t boxLength = MockBox::peekLength(buffer.get());
147         if (boxLength > buffer->byteLength())
148             break;
149
150         String type = MockBox::peekType(buffer.get());
151         if (type == MockInitializationBox::type()) {
152             MockInitializationBox initBox = MockInitializationBox(buffer.get());
153             didReceiveInitializationSegment(initBox);
154         } else if (type == MockSampleBox::type()) {
155             MockSampleBox sampleBox = MockSampleBox(buffer.get());
156             didReceiveSample(sampleBox);
157         } else
158             result = SourceBufferPrivateClient::ParsingFailed;
159
160         m_inputBuffer.remove(0, boxLength);
161     }
162
163     if (m_client)
164         m_client->sourceBufferPrivateAppendComplete(result);
165 }
166
167 void MockSourceBufferPrivate::didReceiveInitializationSegment(const MockInitializationBox& initBox)
168 {
169     if (!m_client)
170         return;
171
172     SourceBufferPrivateClient::InitializationSegment segment;
173     segment.duration = initBox.duration();
174
175     for (auto it = initBox.tracks().begin(); it != initBox.tracks().end(); ++it) {
176         const MockTrackBox& trackBox = *it;
177         if (trackBox.kind() == MockTrackBox::Video) {
178             SourceBufferPrivateClient::InitializationSegment::VideoTrackInformation info;
179             info.track = MockVideoTrackPrivate::create(trackBox);
180             info.description = MockMediaDescription::create(trackBox);
181             segment.videoTracks.append(info);
182         } else if (trackBox.kind() == MockTrackBox::Audio) {
183             SourceBufferPrivateClient::InitializationSegment::AudioTrackInformation info;
184             info.track = MockAudioTrackPrivate::create(trackBox);
185             info.description = MockMediaDescription::create(trackBox);
186             segment.audioTracks.append(info);
187         } else if (trackBox.kind() == MockTrackBox::Text) {
188             SourceBufferPrivateClient::InitializationSegment::TextTrackInformation info;
189             info.track = MockTextTrackPrivate::create(trackBox);
190             info.description = MockMediaDescription::create(trackBox);
191             segment.textTracks.append(info);
192         }
193     }
194
195     m_client->sourceBufferPrivateDidReceiveInitializationSegment(segment);
196 }
197
198
199 void MockSourceBufferPrivate::didReceiveSample(const MockSampleBox& sampleBox)
200 {
201     if (!m_client)
202         return;
203
204     m_client->sourceBufferPrivateDidReceiveSample(MockMediaSample::create(sampleBox));
205 }
206
207 void MockSourceBufferPrivate::abort()
208 {
209 }
210
211 void MockSourceBufferPrivate::resetParserState()
212 {
213 }
214
215 void MockSourceBufferPrivate::removedFromMediaSource()
216 {
217     if (m_mediaSource)
218         m_mediaSource->removeSourceBuffer(this);
219 }
220
221 MediaPlayer::ReadyState MockSourceBufferPrivate::readyState() const
222 {
223     return m_mediaSource ? m_mediaSource->player().readyState() : MediaPlayer::HaveNothing;
224 }
225
226 void MockSourceBufferPrivate::setReadyState(MediaPlayer::ReadyState readyState)
227 {
228     if (m_mediaSource)
229         m_mediaSource->player().setReadyState(readyState);
230 }
231
232 void MockSourceBufferPrivate::setActive(bool isActive)
233 {
234     if (m_mediaSource)
235         m_mediaSource->sourceBufferPrivateDidChangeActiveState(this, isActive);
236 }
237
238 Vector<String> MockSourceBufferPrivate::enqueuedSamplesForTrackID(const AtomicString&)
239 {
240     return m_enqueuedSamples;
241 }
242
243 void MockSourceBufferPrivate::enqueueSample(Ref<MediaSample>&& sample, const AtomicString&)
244 {
245     if (!m_mediaSource)
246         return;
247
248     PlatformSample platformSample = sample->platformSample();
249     if (platformSample.type != PlatformSample::MockSampleBoxType)
250         return;
251
252     auto* box = platformSample.sample.mockSampleBox;
253     if (!box)
254         return;
255
256     m_mediaSource->incrementTotalVideoFrames();
257     if (box->isCorrupted())
258         m_mediaSource->incrementCorruptedFrames();
259     if (box->isDropped())
260         m_mediaSource->incrementDroppedFrames();
261     if (box->isDelayed())
262         m_mediaSource->incrementTotalFrameDelayBy(MediaTime(1, 1));
263
264     m_enqueuedSamples.append(toString(sample.get()));
265 }
266
267 bool MockSourceBufferPrivate::hasVideo() const
268 {
269     return m_client && m_client->sourceBufferPrivateHasVideo();
270 }
271
272 bool MockSourceBufferPrivate::hasAudio() const
273 {
274     return m_client && m_client->sourceBufferPrivateHasAudio();
275 }
276
277 MediaTime MockSourceBufferPrivate::fastSeekTimeForMediaTime(const MediaTime& time, const MediaTime& negativeThreshold, const MediaTime& positiveThreshold)
278 {
279     if (m_client)
280         return m_client->sourceBufferPrivateFastSeekTimeForMediaTime(time, negativeThreshold, positiveThreshold);
281     return time;
282 }
283
284 void MockSourceBufferPrivate::seekToTime(const MediaTime& time)
285 {
286     if (m_client)
287         m_client->sourceBufferPrivateSeekToTime(time);
288 }
289
290 }
291
292 #endif
293