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