2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * Copyright (C) 2013-2014 Apple Inc. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #if ENABLE(MEDIA_SOURCE)
36 #include "ActiveDOMObject.h"
37 #include "AudioTrack.h"
38 #include "EventTarget.h"
39 #include "ExceptionCode.h"
40 #include "GenericEventQueue.h"
41 #include "ScriptWrappable.h"
42 #include "SourceBufferPrivateClient.h"
43 #include "TextTrack.h"
45 #include "VideoTrack.h"
46 #include <runtime/ArrayBufferView.h>
47 #include <wtf/RefCounted.h>
48 #include <wtf/text/WTFString.h>
54 class PlatformTimeRanges;
55 class SourceBufferPrivate;
60 class SourceBuffer final : public RefCounted<SourceBuffer>, public ActiveDOMObject, public EventTargetWithInlineData, public SourceBufferPrivateClient, public AudioTrackClient, public VideoTrackClient, public TextTrackClient {
62 static Ref<SourceBuffer> create(Ref<SourceBufferPrivate>&&, MediaSource*);
64 virtual ~SourceBuffer();
66 // SourceBuffer.idl methods
67 bool updating() const { return m_updating; }
68 RefPtr<TimeRanges> buffered(ExceptionCode&) const;
69 const RefPtr<TimeRanges>& buffered() const;
70 double timestampOffset() const;
71 void setTimestampOffset(double, ExceptionCode&);
73 #if ENABLE(VIDEO_TRACK)
74 VideoTrackList* videoTracks();
75 AudioTrackList* audioTracks();
76 TextTrackList* textTracks();
79 double appendWindowStart() const;
80 void setAppendWindowStart(double, ExceptionCode&);
81 double appendWindowEnd() const;
82 void setAppendWindowEnd(double, ExceptionCode&);
84 void appendBuffer(ArrayBuffer&, ExceptionCode&);
85 void appendBuffer(ArrayBufferView&, ExceptionCode&);
86 void abort(ExceptionCode&);
87 void remove(double start, double end, ExceptionCode&);
88 void remove(const MediaTime&, const MediaTime&, ExceptionCode&);
90 void appendError(bool);
91 void abortIfUpdating();
92 void removedFromMediaSource();
93 void seekToTime(const MediaTime&);
95 bool hasCurrentTime() const;
96 bool hasFutureTime() const;
97 bool canPlayThrough();
99 bool hasVideo() const;
100 bool hasAudio() const;
102 bool active() const { return m_active; }
104 // EventTarget interface
105 ScriptExecutionContext* scriptExecutionContext() const override { return ActiveDOMObject::scriptExecutionContext(); }
106 EventTargetInterface eventTargetInterface() const override { return SourceBufferEventTargetInterfaceType; }
108 using RefCounted<SourceBuffer>::ref;
109 using RefCounted<SourceBuffer>::deref;
113 Document& document() const;
115 enum class AppendMode { Segments, Sequence };
116 AppendMode mode() const { return m_mode; }
117 void setMode(AppendMode, ExceptionCode&);
119 bool shouldGenerateTimestamps() const { return m_shouldGenerateTimestamps; }
120 void setShouldGenerateTimestamps(bool flag) { m_shouldGenerateTimestamps = flag; }
122 void rangeRemoval(const MediaTime&, const MediaTime&);
124 bool isBufferedDirty() const { return m_bufferedDirty; }
125 void setBufferedDirty(bool flag) { m_bufferedDirty = flag; }
127 // ActiveDOMObject API.
128 bool hasPendingActivity() const override;
131 // EventTarget interface
132 void refEventTarget() override { ref(); }
133 void derefEventTarget() override { deref(); }
136 SourceBuffer(Ref<SourceBufferPrivate>&&, MediaSource*);
138 // ActiveDOMObject API.
139 void stop() override;
140 const char* activeDOMObjectName() const override;
141 bool canSuspendForDocumentSuspension() const override;
143 // SourceBufferPrivateClient
144 void sourceBufferPrivateDidReceiveInitializationSegment(SourceBufferPrivate*, const InitializationSegment&) override;
145 void sourceBufferPrivateDidReceiveSample(SourceBufferPrivate*, MediaSample&) override;
146 bool sourceBufferPrivateHasAudio(const SourceBufferPrivate*) const override;
147 bool sourceBufferPrivateHasVideo(const SourceBufferPrivate*) const override;
148 void sourceBufferPrivateDidBecomeReadyForMoreSamples(SourceBufferPrivate*, AtomicString trackID) override;
149 MediaTime sourceBufferPrivateFastSeekTimeForMediaTime(SourceBufferPrivate*, const MediaTime&, const MediaTime& negativeThreshold, const MediaTime& positiveThreshold) override;
150 void sourceBufferPrivateAppendComplete(SourceBufferPrivate*, AppendResult) override;
151 void sourceBufferPrivateDidReceiveRenderingError(SourceBufferPrivate*, int errorCode) override;
154 void audioTrackEnabledChanged(AudioTrack*) override;
157 void videoTrackSelectedChanged(VideoTrack*) override;
160 void textTrackKindChanged(TextTrack*) override;
161 void textTrackModeChanged(TextTrack*) override;
162 void textTrackAddCues(TextTrack*, const TextTrackCueList*) override;
163 void textTrackRemoveCues(TextTrack*, const TextTrackCueList*) override;
164 void textTrackAddCue(TextTrack*, TextTrackCue&) override;
165 void textTrackRemoveCue(TextTrack*, TextTrackCue&) override;
167 bool isRemoved() const;
168 void scheduleEvent(const AtomicString& eventName);
170 void appendBufferInternal(unsigned char*, unsigned, ExceptionCode&);
171 void appendBufferTimerFired();
172 void resetParserState();
174 void setActive(bool);
176 bool validateInitializationSegment(const InitializationSegment&);
178 void reenqueueMediaForTime(TrackBuffer&, AtomicString trackID, const MediaTime&);
179 void provideMediaData(TrackBuffer&, AtomicString trackID);
180 void didDropSample();
181 void evictCodedFrames(size_t newDataSize);
182 size_t maximumBufferSize() const;
184 void monitorBufferingRate();
186 void removeTimerFired();
187 void removeCodedFrames(const MediaTime& start, const MediaTime& end);
189 size_t extraMemoryCost() const;
190 void reportExtraMemoryAllocated();
192 std::unique_ptr<PlatformTimeRanges> bufferedAccountingForEndOfStream() const;
195 friend class Internals;
196 WEBCORE_EXPORT Vector<String> bufferedSamplesForTrackID(const AtomicString&);
198 Ref<SourceBufferPrivate> m_private;
199 MediaSource* m_source;
200 GenericEventQueue m_asyncEventQueue;
201 AppendMode m_mode { AppendMode::Segments };
203 Vector<unsigned char> m_pendingAppendData;
204 Timer m_appendBufferTimer;
206 RefPtr<VideoTrackList> m_videoTracks;
207 RefPtr<AudioTrackList> m_audioTracks;
208 RefPtr<TextTrackList> m_textTracks;
210 Vector<AtomicString> m_videoCodecs;
211 Vector<AtomicString> m_audioCodecs;
212 Vector<AtomicString> m_textCodecs;
214 MediaTime m_timestampOffset;
215 MediaTime m_appendWindowStart;
216 MediaTime m_appendWindowEnd;
218 MediaTime m_groupStartTimestamp;
219 MediaTime m_groupEndTimestamp;
221 HashMap<AtomicString, TrackBuffer> m_trackBufferMap;
222 RefPtr<TimeRanges> m_buffered;
223 bool m_bufferedDirty { true };
225 enum AppendStateType { WaitingForSegment, ParsingInitSegment, ParsingMediaSegment };
226 AppendStateType m_appendState;
228 double m_timeOfBufferingMonitor;
229 double m_bufferedSinceLastMonitor { 0 };
230 double m_averageBufferRate { 0 };
232 size_t m_reportedExtraMemoryCost { 0 };
234 MediaTime m_pendingRemoveStart;
235 MediaTime m_pendingRemoveEnd;
238 bool m_updating { false };
239 bool m_receivedFirstInitializationSegment { false };
240 bool m_active { false };
241 bool m_bufferFull { false };
242 bool m_shouldGenerateTimestamps { false };
245 } // namespace WebCore