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