1/*
2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * Copyright (C) 2013-2014 Apple Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
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
14 * distribution.
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.
18 *
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.
30 */
31
32#ifndef SourceBuffer_h
33#define SourceBuffer_h
34
35#if ENABLE(MEDIA_SOURCE)
36
37#include "ActiveDOMObject.h"
38#include "AudioTrack.h"
39#include "EventTarget.h"
40#include "ExceptionCode.h"
41#include "GenericEventQueue.h"
42#include "ScriptWrappable.h"
43#include "SourceBufferPrivateClient.h"
44#include "TextTrack.h"
45#include "Timer.h"
46#include "VideoTrack.h"
47#include <runtime/ArrayBufferView.h>
48#include <wtf/PassRefPtr.h>
49#include <wtf/RefCounted.h>
50#include <wtf/text/WTFString.h>
51
52namespace WebCore {
53
54class AudioTrackList;
55class MediaSource;
56class PlatformTimeRanges;
57class SourceBufferPrivate;
58class TextTrackList;
59class TimeRanges;
60class VideoTrackList;
61
62class SourceBuffer final : public RefCounted<SourceBuffer>, public ActiveDOMObject, public EventTargetWithInlineData, public ScriptWrappable, public SourceBufferPrivateClient, public AudioTrackClient, public VideoTrackClient, public TextTrackClient {
63public:
64    static PassRef<SourceBuffer> create(PassRef<SourceBufferPrivate>, MediaSource*);
65
66    virtual ~SourceBuffer();
67
68    // SourceBuffer.idl methods
69    bool updating() const { return m_updating; }
70    PassRefPtr<TimeRanges> buffered(ExceptionCode&) const;
71    const RefPtr<TimeRanges>& buffered() const;
72    double timestampOffset() const;
73    void setTimestampOffset(double, ExceptionCode&);
74    void appendBuffer(PassRefPtr<ArrayBuffer> data, ExceptionCode&);
75    void appendBuffer(PassRefPtr<ArrayBufferView> data, ExceptionCode&);
76    void abort(ExceptionCode&);
77    void remove(double start, double end, ExceptionCode&);
78
79    void abortIfUpdating();
80    void removedFromMediaSource();
81    const MediaTime& highestPresentationEndTimestamp() const { return m_highestPresentationEndTimestamp; }
82    void seekToTime(const MediaTime&);
83
84#if ENABLE(VIDEO_TRACK)
85    VideoTrackList* videoTracks();
86    AudioTrackList* audioTracks();
87    TextTrackList* textTracks();
88#endif
89
90    bool hasCurrentTime() const;
91    bool hasFutureTime() const;
92    bool canPlayThrough();
93
94    bool hasVideo() const;
95    bool hasAudio() const;
96
97    bool active() const { return m_active; }
98
99    // ActiveDOMObject interface
100    virtual bool hasPendingActivity() const override;
101    virtual void stop() override;
102
103    // EventTarget interface
104    virtual ScriptExecutionContext* scriptExecutionContext() const override { return ActiveDOMObject::scriptExecutionContext(); }
105    virtual EventTargetInterface eventTargetInterface() const override { return SourceBufferEventTargetInterfaceType; }
106
107    using RefCounted<SourceBuffer>::ref;
108    using RefCounted<SourceBuffer>::deref;
109
110    struct TrackBuffer;
111
112    Document& document() const;
113
114protected:
115    // EventTarget interface
116    virtual void refEventTarget() override { ref(); }
117    virtual void derefEventTarget() override { deref(); }
118
119private:
120    SourceBuffer(PassRef<SourceBufferPrivate>, MediaSource*);
121
122    // SourceBufferPrivateClient
123    virtual void sourceBufferPrivateDidEndStream(SourceBufferPrivate*, const WTF::AtomicString&) override;
124    virtual void sourceBufferPrivateDidReceiveInitializationSegment(SourceBufferPrivate*, const InitializationSegment&) override;
125    virtual void sourceBufferPrivateDidReceiveSample(SourceBufferPrivate*, PassRefPtr<MediaSample>) override;
126    virtual bool sourceBufferPrivateHasAudio(const SourceBufferPrivate*) const override;
127    virtual bool sourceBufferPrivateHasVideo(const SourceBufferPrivate*) const override;
128    virtual void sourceBufferPrivateDidBecomeReadyForMoreSamples(SourceBufferPrivate*, AtomicString trackID) override;
129    virtual MediaTime sourceBufferPrivateFastSeekTimeForMediaTime(SourceBufferPrivate*, const MediaTime&, const MediaTime& negativeThreshold, const MediaTime& positiveThreshold);
130    virtual void sourceBufferPrivateAppendComplete(SourceBufferPrivate*, AppendResult) override;
131    virtual void sourceBufferPrivateDidReceiveRenderingError(SourceBufferPrivate*, int errorCode) override;
132
133    // AudioTrackClient
134    virtual void audioTrackEnabledChanged(AudioTrack*) override;
135
136    // VideoTrackClient
137    virtual void videoTrackSelectedChanged(VideoTrack*) override;
138
139    // TextTrackClient
140    virtual void textTrackKindChanged(TextTrack*) override;
141    virtual void textTrackModeChanged(TextTrack*) override;
142    virtual void textTrackAddCues(TextTrack*, const TextTrackCueList*) override;
143    virtual void textTrackRemoveCues(TextTrack*, const TextTrackCueList*) override;
144    virtual void textTrackAddCue(TextTrack*, PassRefPtr<TextTrackCue>) override;
145    virtual void textTrackRemoveCue(TextTrack*, PassRefPtr<TextTrackCue>) override;
146
147    static const WTF::AtomicString& decodeError();
148    static const WTF::AtomicString& networkError();
149
150    bool isRemoved() const;
151    void scheduleEvent(const AtomicString& eventName);
152
153    void appendBufferInternal(unsigned char*, unsigned, ExceptionCode&);
154    void appendBufferTimerFired(Timer<SourceBuffer>&);
155
156    void setActive(bool);
157
158    bool validateInitializationSegment(const InitializationSegment&);
159
160    void reenqueueMediaForTime(TrackBuffer&, AtomicString trackID, const MediaTime&);
161    void provideMediaData(TrackBuffer&, AtomicString trackID);
162    void didDropSample();
163    void evictCodedFrames(size_t newDataSize);
164    size_t maximumBufferSize() const;
165
166    void monitorBufferingRate();
167
168    void removeTimerFired(Timer<SourceBuffer>*);
169    void removeCodedFrames(const MediaTime& start, const MediaTime& end);
170
171    size_t extraMemoryCost() const;
172    void reportExtraMemoryCost();
173
174    std::unique_ptr<PlatformTimeRanges> bufferedAccountingForEndOfStream() const;
175
176    // Internals
177    friend class Internals;
178    Vector<String> bufferedSamplesForTrackID(const AtomicString&);
179
180    Ref<SourceBufferPrivate> m_private;
181    MediaSource* m_source;
182    GenericEventQueue m_asyncEventQueue;
183
184    Vector<unsigned char> m_pendingAppendData;
185    Timer<SourceBuffer> m_appendBufferTimer;
186
187    RefPtr<VideoTrackList> m_videoTracks;
188    RefPtr<AudioTrackList> m_audioTracks;
189    RefPtr<TextTrackList> m_textTracks;
190
191    Vector<AtomicString> m_videoCodecs;
192    Vector<AtomicString> m_audioCodecs;
193    Vector<AtomicString> m_textCodecs;
194
195    MediaTime m_timestampOffset;
196    MediaTime m_highestPresentationEndTimestamp;
197
198    HashMap<AtomicString, TrackBuffer> m_trackBufferMap;
199    RefPtr<TimeRanges> m_buffered;
200
201    enum AppendStateType { WaitingForSegment, ParsingInitSegment, ParsingMediaSegment };
202    AppendStateType m_appendState;
203
204    double m_timeOfBufferingMonitor;
205    double m_bufferedSinceLastMonitor;
206    double m_averageBufferRate;
207
208    size_t m_reportedExtraMemoryCost;
209
210    MediaTime m_pendingRemoveStart;
211    MediaTime m_pendingRemoveEnd;
212    Timer<SourceBuffer> m_removeTimer;
213
214    bool m_updating;
215    bool m_receivedFirstInitializationSegment;
216    bool m_active;
217    bool m_bufferFull;
218};
219
220} // namespace WebCore
221
222#endif
223
224#endif
225