2 * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
28 #if ENABLE(MEDIA_SOURCE) && USE(AVFOUNDATION)
30 #include "SourceBufferPrivate.h"
31 #include <dispatch/group.h>
32 #include <dispatch/semaphore.h>
33 #include <wtf/Deque.h>
34 #include <wtf/HashMap.h>
35 #include <wtf/MediaTime.h>
36 #include <wtf/OSObjectPtr.h>
37 #include <wtf/RefPtr.h>
38 #include <wtf/RetainPtr.h>
39 #include <wtf/Vector.h>
40 #include <wtf/WeakPtr.h>
41 #include <wtf/text/AtomicString.h>
44 OBJC_CLASS AVStreamDataParser;
45 OBJC_CLASS AVSampleBufferAudioRenderer;
46 OBJC_CLASS AVSampleBufferDisplayLayer;
50 OBJC_CLASS WebAVStreamDataParserListener;
51 OBJC_CLASS WebAVSampleBufferErrorListener;
53 typedef struct opaqueCMSampleBuffer *CMSampleBufferRef;
54 typedef const struct opaqueCMFormatDescription *CMFormatDescriptionRef;
59 class CDMInstanceFairPlayStreamingAVFObjC;
60 class CDMSessionMediaSourceAVFObjC;
61 class MediaSourcePrivateAVFObjC;
63 class AudioTrackPrivate;
64 class VideoTrackPrivate;
65 class AudioTrackPrivateMediaSourceAVFObjC;
66 class VideoTrackPrivateMediaSourceAVFObjC;
67 class WebCoreDecompressionSession;
69 class SourceBufferPrivateAVFObjCErrorClient {
71 virtual ~SourceBufferPrivateAVFObjCErrorClient() = default;
72 virtual void layerDidReceiveError(AVSampleBufferDisplayLayer *, NSError *, bool& shouldIgnore) = 0;
73 ALLOW_NEW_API_WITHOUT_GUARDS_BEGIN
74 virtual void rendererDidReceiveError(AVSampleBufferAudioRenderer *, NSError *, bool& shouldIgnore) = 0;
75 ALLOW_NEW_API_WITHOUT_GUARDS_END
78 class SourceBufferPrivateAVFObjC final : public SourceBufferPrivate {
80 static RefPtr<SourceBufferPrivateAVFObjC> create(MediaSourcePrivateAVFObjC*);
81 virtual ~SourceBufferPrivateAVFObjC();
83 void clearMediaSource() { m_mediaSource = nullptr; }
85 // AVStreamDataParser delegate methods
86 void didParseStreamDataAsAsset(AVAsset*);
87 void didFailToParseStreamDataWithError(NSError*);
88 void didProvideMediaDataForTrackID(int trackID, CMSampleBufferRef, const String& mediaType, unsigned flags);
89 void didReachEndOfTrackWithTrackID(int trackID, const String& mediaType);
90 void willProvideContentKeyRequestInitializationDataForTrackID(int trackID);
91 void didProvideContentKeyRequestInitializationDataForTrackID(NSData*, int trackID, OSObjectPtr<dispatch_semaphore_t>);
93 bool processCodedFrame(int trackID, CMSampleBufferRef, const String& mediaType);
95 bool hasVideo() const;
96 bool hasSelectedVideo() const;
97 bool hasAudio() const;
99 void trackDidChangeEnabled(VideoTrackPrivateMediaSourceAVFObjC*);
100 void trackDidChangeEnabled(AudioTrackPrivateMediaSourceAVFObjC*);
103 void seekToTime(MediaTime);
104 MediaTime fastSeekTimeForMediaTime(MediaTime, MediaTime negativeThreshold, MediaTime positiveThreshold);
105 FloatSize naturalSize();
107 int protectedTrackID() const { return m_protectedTrackID; }
108 AVStreamDataParser* parser() const { return m_parser.get(); }
109 void setCDMSession(CDMSessionMediaSourceAVFObjC*);
110 void setCDMInstance(CDMInstance*);
114 void registerForErrorNotifications(SourceBufferPrivateAVFObjCErrorClient*);
115 void unregisterForErrorNotifications(SourceBufferPrivateAVFObjCErrorClient*);
116 void layerDidReceiveError(AVSampleBufferDisplayLayer *, NSError *);
117 void outputObscuredDueToInsufficientExternalProtectionChanged(bool);
118 ALLOW_NEW_API_WITHOUT_GUARDS_BEGIN
119 void rendererDidReceiveError(AVSampleBufferAudioRenderer *, NSError *);
120 ALLOW_NEW_API_WITHOUT_GUARDS_END
122 void setVideoLayer(AVSampleBufferDisplayLayer*);
123 void setDecompressionSession(WebCoreDecompressionSession*);
125 void bufferWasConsumed();
128 explicit SourceBufferPrivateAVFObjC(MediaSourcePrivateAVFObjC*);
130 // SourceBufferPrivate overrides
131 void setClient(SourceBufferPrivateClient*) final;
132 void append(Vector<unsigned char>&&) final;
134 void resetParserState() final;
135 void removedFromMediaSource() final;
136 MediaPlayer::ReadyState readyState() const final;
137 void setReadyState(MediaPlayer::ReadyState) final;
138 void flush(const AtomicString& trackID) final;
139 void enqueueSample(Ref<MediaSample>&&, const AtomicString& trackID) final;
140 bool isReadyForMoreSamples(const AtomicString& trackID) final;
141 void setActive(bool) final;
142 void notifyClientWhenReadyForMoreSamples(const AtomicString& trackID) final;
143 bool canSwitchToType(const ContentType&) final;
145 void didBecomeReadyForMoreSamples(int trackID);
146 void appendCompleted();
147 void destroyParser();
148 void destroyRenderers();
151 ALLOW_NEW_API_WITHOUT_GUARDS_BEGIN
152 void flush(AVSampleBufferAudioRenderer *);
153 ALLOW_NEW_API_WITHOUT_GUARDS_END
155 WeakPtr<SourceBufferPrivateAVFObjC> createWeakPtr() { return m_weakFactory.createWeakPtr(*this); }
157 Vector<RefPtr<VideoTrackPrivateMediaSourceAVFObjC>> m_videoTracks;
158 Vector<RefPtr<AudioTrackPrivateMediaSourceAVFObjC>> m_audioTracks;
159 Vector<SourceBufferPrivateAVFObjCErrorClient*> m_errorClients;
161 WeakPtrFactory<SourceBufferPrivateAVFObjC> m_weakFactory;
162 WeakPtrFactory<SourceBufferPrivateAVFObjC> m_appendWeakFactory;
164 RetainPtr<AVStreamDataParser> m_parser;
165 RetainPtr<AVAsset> m_asset;
166 RetainPtr<AVSampleBufferDisplayLayer> m_displayLayer;
167 ALLOW_NEW_API_WITHOUT_GUARDS_BEGIN
168 HashMap<int, RetainPtr<AVSampleBufferAudioRenderer>> m_audioRenderers;
169 ALLOW_NEW_API_WITHOUT_GUARDS_END
170 RetainPtr<WebAVStreamDataParserListener> m_delegate;
171 RetainPtr<WebAVSampleBufferErrorListener> m_errorListener;
172 RetainPtr<NSError> m_hdcpError;
173 OSObjectPtr<dispatch_semaphore_t> m_hasSessionSemaphore;
174 OSObjectPtr<dispatch_group_t> m_isAppendingGroup;
175 RefPtr<WebCoreDecompressionSession> m_decompressionSession;
177 MediaSourcePrivateAVFObjC* m_mediaSource;
178 SourceBufferPrivateClient* m_client { nullptr };
179 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
180 CDMSessionMediaSourceAVFObjC* m_session { nullptr };
182 #if ENABLE(ENCRYPTED_MEDIA) && HAVE(AVCONTENTKEYSESSION)
183 RefPtr<CDMInstanceFairPlayStreamingAVFObjC> m_cdmInstance;
186 std::optional<FloatSize> m_cachedSize;
187 FloatSize m_currentSize;
188 bool m_parsingSucceeded { true };
189 bool m_parserStateWasReset { false };
190 bool m_discardSamplesUntilNextInitializationSegment { false };
191 int m_enabledVideoTrackID { -1 };
192 int m_protectedTrackID { -1 };
197 #endif // ENABLE(MEDIA_SOURCE) && USE(AVFOUNDATION)