| /* |
| * Copyright (C) 2013 Google Inc. All rights reserved. |
| * Copyright (C) 2013-2020 Apple Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are |
| * met: |
| * |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above |
| * copyright notice, this list of conditions and the following disclaimer |
| * in the documentation and/or other materials provided with the |
| * distribution. |
| * * Neither the name of Google Inc. nor the names of its |
| * contributors may be used to endorse or promote products derived from |
| * this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #pragma once |
| |
| #if ENABLE(MEDIA_SOURCE) |
| |
| #include "ActiveDOMObject.h" |
| #include "AudioTrackClient.h" |
| #include "EventTarget.h" |
| #include "ExceptionOr.h" |
| #include "SourceBufferPrivate.h" |
| #include "SourceBufferPrivateClient.h" |
| #include "TextTrackClient.h" |
| #include "Timer.h" |
| #include "VideoTrackClient.h" |
| #include <wtf/LoggerHelper.h> |
| #include <wtf/Observer.h> |
| |
| namespace WebCore { |
| |
| class AudioTrackList; |
| class BufferSource; |
| class MediaSource; |
| class PlatformTimeRanges; |
| class SourceBufferPrivate; |
| class TextTrackList; |
| class TimeRanges; |
| class VideoTrackList; |
| class WebCoreOpaqueRoot; |
| |
| class SourceBuffer final |
| : public RefCounted<SourceBuffer> |
| , public ActiveDOMObject |
| , public EventTargetWithInlineData |
| , private SourceBufferPrivateClient |
| , private AudioTrackClient |
| , private VideoTrackClient |
| , private TextTrackClient |
| #if !RELEASE_LOG_DISABLED |
| , private LoggerHelper |
| #endif |
| { |
| WTF_MAKE_ISO_ALLOCATED(SourceBuffer); |
| public: |
| using WeakValueType = EventTarget::WeakValueType; |
| using EventTarget::weakPtrFactory; |
| |
| 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); |
| |
| VideoTrackList& videoTracks(); |
| VideoTrackList* videoTracksIfExists() const { return m_videoTracks.get(); } |
| AudioTrackList& audioTracks(); |
| AudioTrackList* audioTracksIfExists() const { return m_audioTracks.get(); } |
| TextTrackList& textTracks(); |
| TextTrackList* textTracksIfExists() const { return m_textTracks.get(); } |
| |
| 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_private->buffered()); return *m_private->buffered(); } |
| |
| void abortIfUpdating(); |
| void removedFromMediaSource(); |
| void seekToTime(const MediaTime&); |
| |
| bool canPlayThroughRange(PlatformTimeRanges&); |
| |
| bool hasVideo() const; |
| |
| bool active() const { return m_active; } |
| |
| // EventTarget |
| ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); } |
| |
| using RefCounted::ref; |
| using RefCounted::deref; |
| |
| Document& document() const; |
| enum class AppendMode { Segments, Sequence }; |
| AppendMode mode() const { return m_mode; } |
| ExceptionOr<void> setMode(AppendMode); |
| |
| WEBCORE_EXPORT void setShouldGenerateTimestamps(bool flag); |
| |
| bool isBufferedDirty() const; |
| void setBufferedDirty(bool flag); |
| |
| MediaTime highestPresentationTimestamp() const; |
| void readyStateChanged(); |
| |
| size_t memoryCost() const; |
| |
| void setMediaSourceEnded(bool isEnded); |
| |
| #if !RELEASE_LOG_DISABLED |
| const Logger& logger() const final { return m_logger.get(); } |
| const void* logIdentifier() const final { return m_logIdentifier; } |
| const char* logClassName() const final { return "SourceBuffer"; } |
| WTFLogChannel& logChannel() const final; |
| #endif |
| |
| WebCoreOpaqueRoot opaqueRoot(); |
| |
| private: |
| SourceBuffer(Ref<SourceBufferPrivate>&&, MediaSource*); |
| |
| void refEventTarget() final { ref(); } |
| void derefEventTarget() final { deref(); } |
| |
| // ActiveDOMObject. |
| void stop() final; |
| const char* activeDOMObjectName() const final; |
| bool virtualHasPendingActivity() const final; |
| |
| // SourceBufferPrivateClient |
| void sourceBufferPrivateDidReceiveInitializationSegment(InitializationSegment&&, CompletionHandler<void()>&&) final; |
| void sourceBufferPrivateStreamEndedWithDecodeError() final; |
| void sourceBufferPrivateAppendError(bool decodeError) final; |
| void sourceBufferPrivateAppendComplete(AppendResult) final; |
| void sourceBufferPrivateHighestPresentationTimestampChanged(const MediaTime&) final; |
| void sourceBufferPrivateDurationChanged(const MediaTime& duration) final; |
| void sourceBufferPrivateDidParseSample(double sampleDuration) final; |
| void sourceBufferPrivateDidDropSample() final; |
| void sourceBufferPrivateBufferedDirtyChanged(bool) final; |
| void sourceBufferPrivateDidReceiveRenderingError(int64_t errorCode) final; |
| void sourceBufferPrivateReportExtraMemoryCost(uint64_t) final; |
| |
| // AudioTrackClient |
| void audioTrackEnabledChanged(AudioTrack&) final; |
| void audioTrackKindChanged(AudioTrack&) final; |
| void audioTrackLabelChanged(AudioTrack&) final; |
| void audioTrackLanguageChanged(AudioTrack&) final; |
| |
| // TextTrackClient |
| void textTrackKindChanged(TextTrack&) final; |
| void textTrackModeChanged(TextTrack&) final; |
| void textTrackLanguageChanged(TextTrack&) final; |
| |
| // VideoTrackClient |
| void videoTrackKindChanged(VideoTrack&) final; |
| void videoTrackLabelChanged(VideoTrack&) final; |
| void videoTrackLanguageChanged(VideoTrack&) final; |
| void videoTrackSelectedChanged(VideoTrack&) final; |
| |
| // EventTarget |
| EventTargetInterface eventTargetInterface() const final { return SourceBufferEventTargetInterfaceType; } |
| |
| bool isRemoved() const; |
| void scheduleEvent(const AtomString& eventName); |
| |
| ExceptionOr<void> appendBufferInternal(const unsigned char*, unsigned); |
| void appendBufferTimerFired(); |
| void resetParserState(); |
| |
| void setActive(bool); |
| |
| bool validateInitializationSegment(const InitializationSegment&); |
| |
| uint64_t maximumBufferSize() const; |
| |
| void monitorBufferingRate(); |
| |
| void removeTimerFired(); |
| |
| void reportExtraMemoryAllocated(uint64_t extraMemory); |
| |
| void appendError(bool); |
| |
| bool hasAudio() const; |
| |
| void rangeRemoval(const MediaTime&, const MediaTime&); |
| |
| friend class Internals; |
| WEBCORE_EXPORT void bufferedSamplesForTrackId(const AtomString&, CompletionHandler<void(Vector<String>&&)>&&); |
| WEBCORE_EXPORT void enqueuedSamplesForTrackID(const AtomString&, CompletionHandler<void(Vector<String>&&)>&&); |
| WEBCORE_EXPORT MediaTime minimumUpcomingPresentationTimeForTrackID(const AtomString&); |
| WEBCORE_EXPORT void setMaximumQueueDepthForTrackID(const AtomString&, uint64_t); |
| |
| Ref<SourceBufferPrivate> m_private; |
| MediaSource* m_source; |
| AppendMode m_mode { AppendMode::Segments }; |
| |
| WTF::Observer<WebCoreOpaqueRoot()> m_opaqueRootProvider; |
| |
| RefPtr<SharedBuffer> m_pendingAppendData; |
| Timer m_appendBufferTimer; |
| |
| RefPtr<VideoTrackList> m_videoTracks; |
| RefPtr<AudioTrackList> m_audioTracks; |
| RefPtr<TextTrackList> m_textTracks; |
| |
| Vector<AtomString> m_videoCodecs; |
| Vector<AtomString> m_audioCodecs; |
| Vector<AtomString> m_textCodecs; |
| |
| MediaTime m_appendWindowStart; |
| MediaTime m_appendWindowEnd; |
| MediaTime m_highestPresentationTimestamp; |
| |
| enum AppendStateType { WaitingForSegment, ParsingInitSegment, ParsingMediaSegment }; |
| AppendStateType m_appendState; |
| |
| MonotonicTime m_timeOfBufferingMonitor; |
| double m_bufferedSinceLastMonitor { 0 }; |
| double m_averageBufferRate { 0 }; |
| bool m_bufferedDirty { true }; |
| |
| // Can only grow. |
| uint64_t m_reportedExtraMemoryCost { 0 }; |
| // Can grow and shrink. |
| uint64_t m_extraMemoryCost { 0 }; |
| |
| MediaTime m_pendingRemoveStart; |
| MediaTime m_pendingRemoveEnd; |
| Timer m_removeTimer; |
| |
| bool m_updating { false }; |
| bool m_receivedFirstInitializationSegment { false }; |
| bool m_active { false }; |
| bool m_shouldGenerateTimestamps { false }; |
| bool m_pendingInitializationSegmentForChangeType { false }; |
| |
| #if !RELEASE_LOG_DISABLED |
| Ref<const Logger> m_logger; |
| const void* m_logIdentifier; |
| #endif |
| }; |
| |
| } // namespace WebCore |
| |
| #endif |