#pragma once
#if ENABLE(MEDIA_SOURCE)
#include "ActiveDOMObject.h"
#include "AudioTrack.h"
#include "EventTarget.h"
#include "ExceptionOr.h"
#include "GenericEventQueue.h"
#include "SourceBufferPrivateClient.h"
#include "TextTrack.h"
#include "Timer.h"
#include "VideoTrack.h"
namespace WebCore {
class AudioTrackList;
class BufferSource;
class MediaSource;
class PlatformTimeRanges;
class SourceBufferPrivate;
class TextTrackList;
class TimeRanges;
class VideoTrackList;
class SourceBuffer final : public RefCounted<SourceBuffer>, public ActiveDOMObject, public EventTargetWithInlineData, private SourceBufferPrivateClient, private AudioTrackClient, private VideoTrackClient, private TextTrackClient {
public:
static Ref<SourceBuffer> create(Ref<SourceBufferPrivate>&&, MediaSource*);
virtual ~SourceBuffer();
bool updating() const { return m_updating; }
ExceptionOr<Ref<TimeRanges>> buffered() const;
double timestampOffset() const;
ExceptionOr<void> setTimestampOffset(double);
#if ENABLE(VIDEO_TRACK)
VideoTrackList& videoTracks();
AudioTrackList& audioTracks();
TextTrackList& textTracks();
#endif
double appendWindowStart() const;
ExceptionOr<void> setAppendWindowStart(double);
double appendWindowEnd() const;
ExceptionOr<void> setAppendWindowEnd(double);
ExceptionOr<void> appendBuffer(const BufferSource&);
ExceptionOr<void> abort();
ExceptionOr<void> remove(double start, double end);
ExceptionOr<void> remove(const MediaTime&, const MediaTime&);
ExceptionOr<void> changeType(const String&);
const TimeRanges& bufferedInternal() const { ASSERT(m_buffered); return *m_buffered; }
void abortIfUpdating();
void removedFromMediaSource();
void seekToTime(const MediaTime&);
bool canPlayThroughRange(PlatformTimeRanges&);
bool hasVideo() const;
bool active() const { return m_active; }
ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); }
using RefCounted::ref;
using RefCounted::deref;
struct TrackBuffer;
Document& document() const;
enum class AppendMode { Segments, Sequence };
AppendMode mode() const { return m_mode; }
ExceptionOr<void> setMode(AppendMode);
void setShouldGenerateTimestamps(bool flag) { m_shouldGenerateTimestamps = flag; }
bool isBufferedDirty() const { return m_bufferedDirty; }
void setBufferedDirty(bool flag) { m_bufferedDirty = flag; }
MediaTime highestPresentationTimestamp() const;
void readyStateChanged();
bool hasPendingActivity() const final;
void trySignalAllSamplesEnqueued();
private:
SourceBuffer(Ref<SourceBufferPrivate>&&, MediaSource*);
void refEventTarget() final { ref(); }
void derefEventTarget() final { deref(); }
void suspend(ReasonForSuspension) final;
void resume() final;
void stop() final;
const char* activeDOMObjectName() const final;
bool canSuspendForDocumentSuspension() const final;
void sourceBufferPrivateDidReceiveInitializationSegment(const InitializationSegment&) final;
void sourceBufferPrivateDidReceiveSample(MediaSample&) final;
bool sourceBufferPrivateHasAudio() const final;
bool sourceBufferPrivateHasVideo() const final;
void sourceBufferPrivateReenqueSamples(const AtomicString& trackID) final;
void sourceBufferPrivateDidBecomeReadyForMoreSamples(const AtomicString& trackID) final;
MediaTime sourceBufferPrivateFastSeekTimeForMediaTime(const MediaTime&, const MediaTime& negativeThreshold, const MediaTime& positiveThreshold) final;
void sourceBufferPrivateAppendComplete(AppendResult) final;
void sourceBufferPrivateDidReceiveRenderingError(int errorCode) final;
void audioTrackEnabledChanged(AudioTrack&) final;
void videoTrackSelectedChanged(VideoTrack&) final;
void textTrackKindChanged(TextTrack&) final;
void textTrackModeChanged(TextTrack&) final;
void textTrackAddCues(TextTrack&, const TextTrackCueList&) final;
void textTrackRemoveCues(TextTrack&, const TextTrackCueList&) final;
void textTrackAddCue(TextTrack&, TextTrackCue&) final;
void textTrackRemoveCue(TextTrack&, TextTrackCue&) final;
EventTargetInterface eventTargetInterface() const final { return SourceBufferEventTargetInterfaceType; }
bool isRemoved() const;
void scheduleEvent(const AtomicString& eventName);
ExceptionOr<void> appendBufferInternal(const unsigned char*, unsigned);
void appendBufferTimerFired();
void resetParserState();
void setActive(bool);
bool validateInitializationSegment(const InitializationSegment&);
void reenqueueMediaForTime(TrackBuffer&, const AtomicString& trackID, const MediaTime&);
void provideMediaData(TrackBuffer&, const AtomicString& trackID);
void didDropSample();
void evictCodedFrames(size_t newDataSize);
size_t maximumBufferSize() const;
void monitorBufferingRate();
void removeTimerFired();
void removeCodedFrames(const MediaTime& start, const MediaTime& end);
size_t extraMemoryCost() const;
void reportExtraMemoryAllocated();
void updateBufferedFromTrackBuffers();
void appendError(bool);
bool hasAudio() const;
void rangeRemoval(const MediaTime&, const MediaTime&);
void trySignalAllSamplesInTrackEnqueued(const AtomicString&);
friend class Internals;
WEBCORE_EXPORT Vector<String> bufferedSamplesForTrackID(const AtomicString&);
WEBCORE_EXPORT Vector<String> enqueuedSamplesForTrackID(const AtomicString&);
Ref<SourceBufferPrivate> m_private;
MediaSource* m_source;
GenericEventQueue m_asyncEventQueue;
AppendMode m_mode { AppendMode::Segments };
Vector<unsigned char> m_pendingAppendData;
Timer m_appendBufferTimer;
RefPtr<VideoTrackList> m_videoTracks;
RefPtr<AudioTrackList> m_audioTracks;
RefPtr<TextTrackList> m_textTracks;
Vector<AtomicString> m_videoCodecs;
Vector<AtomicString> m_audioCodecs;
Vector<AtomicString> m_textCodecs;
MediaTime m_timestampOffset;
MediaTime m_appendWindowStart;
MediaTime m_appendWindowEnd;
MediaTime m_groupStartTimestamp;
MediaTime m_groupEndTimestamp;
HashMap<AtomicString, TrackBuffer> m_trackBufferMap;
RefPtr<TimeRanges> m_buffered;
bool m_bufferedDirty { true };
enum AppendStateType { WaitingForSegment, ParsingInitSegment, ParsingMediaSegment };
AppendStateType m_appendState;
MonotonicTime m_timeOfBufferingMonitor;
double m_bufferedSinceLastMonitor { 0 };
double m_averageBufferRate { 0 };
size_t m_reportedExtraMemoryCost { 0 };
MediaTime m_pendingRemoveStart;
MediaTime m_pendingRemoveEnd;
Timer m_removeTimer;
bool m_updating { false };
bool m_receivedFirstInitializationSegment { false };
bool m_active { false };
bool m_bufferFull { false };
bool m_shouldGenerateTimestamps { false };
bool m_pendingInitializationSegmentForChangeType { false };
};
}
#endif