[WTF] Use Semaphore and BinarySemaphore instead of dispatch_semaphore_t
[WebKit-https.git] / Source / WebCore / platform / graphics / avfoundation / objc / SourceBufferPrivateAVFObjC.h
1 /*
2  * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
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.
12  *
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. 
24  */
25
26 #pragma once
27
28 #if ENABLE(MEDIA_SOURCE) && USE(AVFOUNDATION)
29
30 #include "SourceBufferPrivate.h"
31 #include <dispatch/group.h>
32 #include <wtf/Box.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>
42 #include <wtf/threads/BinarySemaphore.h>
43
44 OBJC_CLASS AVAsset;
45 OBJC_CLASS AVStreamDataParser;
46 OBJC_CLASS AVSampleBufferAudioRenderer;
47 OBJC_CLASS AVSampleBufferDisplayLayer;
48 OBJC_CLASS NSData;
49 OBJC_CLASS NSError;
50 OBJC_CLASS NSObject;
51 OBJC_CLASS WebAVStreamDataParserListener;
52 OBJC_CLASS WebAVSampleBufferErrorListener;
53
54 typedef struct opaqueCMSampleBuffer *CMSampleBufferRef;
55 typedef const struct opaqueCMFormatDescription *CMFormatDescriptionRef;
56
57 namespace WebCore {
58
59 class CDMInstance;
60 class CDMInstanceFairPlayStreamingAVFObjC;
61 class CDMSessionMediaSourceAVFObjC;
62 class MediaSourcePrivateAVFObjC;
63 class TimeRanges;
64 class AudioTrackPrivate;
65 class VideoTrackPrivate;
66 class AudioTrackPrivateMediaSourceAVFObjC;
67 class VideoTrackPrivateMediaSourceAVFObjC;
68 class WebCoreDecompressionSession;
69
70 class SourceBufferPrivateAVFObjCErrorClient {
71 public:
72     virtual ~SourceBufferPrivateAVFObjCErrorClient() = default;
73     virtual void layerDidReceiveError(AVSampleBufferDisplayLayer *, NSError *, bool& shouldIgnore) = 0;
74     ALLOW_NEW_API_WITHOUT_GUARDS_BEGIN
75     virtual void rendererDidReceiveError(AVSampleBufferAudioRenderer *, NSError *, bool& shouldIgnore) = 0;
76     ALLOW_NEW_API_WITHOUT_GUARDS_END
77 };
78
79 class SourceBufferPrivateAVFObjC final : public SourceBufferPrivate {
80 public:
81     static RefPtr<SourceBufferPrivateAVFObjC> create(MediaSourcePrivateAVFObjC*);
82     virtual ~SourceBufferPrivateAVFObjC();
83
84     void clearMediaSource() { m_mediaSource = nullptr; }
85
86     // AVStreamDataParser delegate methods
87     void didParseStreamDataAsAsset(AVAsset*);
88     void didFailToParseStreamDataWithError(NSError*);
89     void didProvideMediaDataForTrackID(int trackID, CMSampleBufferRef, const String& mediaType, unsigned flags);
90     void didReachEndOfTrackWithTrackID(int trackID, const String& mediaType);
91     void willProvideContentKeyRequestInitializationDataForTrackID(int trackID);
92     void didProvideContentKeyRequestInitializationDataForTrackID(NSData*, int trackID, Box<BinarySemaphore>);
93
94     bool processCodedFrame(int trackID, CMSampleBufferRef, const String& mediaType);
95
96     bool hasVideo() const;
97     bool hasSelectedVideo() const;
98     bool hasAudio() const;
99
100     void trackDidChangeEnabled(VideoTrackPrivateMediaSourceAVFObjC*);
101     void trackDidChangeEnabled(AudioTrackPrivateMediaSourceAVFObjC*);
102
103     void willSeek();
104     void seekToTime(MediaTime);
105     MediaTime fastSeekTimeForMediaTime(MediaTime, MediaTime negativeThreshold, MediaTime positiveThreshold);
106     FloatSize naturalSize();
107
108     int protectedTrackID() const { return m_protectedTrackID; }
109     AVStreamDataParser* parser() const { return m_parser.get(); }
110     void setCDMSession(CDMSessionMediaSourceAVFObjC*);
111     void setCDMInstance(CDMInstance*);
112
113     void flush();
114
115     void registerForErrorNotifications(SourceBufferPrivateAVFObjCErrorClient*);
116     void unregisterForErrorNotifications(SourceBufferPrivateAVFObjCErrorClient*);
117     void layerDidReceiveError(AVSampleBufferDisplayLayer *, NSError *);
118     void outputObscuredDueToInsufficientExternalProtectionChanged(bool);
119     ALLOW_NEW_API_WITHOUT_GUARDS_BEGIN
120     void rendererDidReceiveError(AVSampleBufferAudioRenderer *, NSError *);
121     ALLOW_NEW_API_WITHOUT_GUARDS_END
122
123     void setVideoLayer(AVSampleBufferDisplayLayer*);
124     void setDecompressionSession(WebCoreDecompressionSession*);
125
126     void bufferWasConsumed();
127
128 private:
129     explicit SourceBufferPrivateAVFObjC(MediaSourcePrivateAVFObjC*);
130
131     // SourceBufferPrivate overrides
132     void setClient(SourceBufferPrivateClient*) final;
133     void append(Vector<unsigned char>&&) final;
134     void abort() final;
135     void resetParserState() final;
136     void removedFromMediaSource() final;
137     MediaPlayer::ReadyState readyState() const final;
138     void setReadyState(MediaPlayer::ReadyState) final;
139     void flush(const AtomicString& trackID) final;
140     void enqueueSample(Ref<MediaSample>&&, const AtomicString& trackID) final;
141     bool isReadyForMoreSamples(const AtomicString& trackID) final;
142     void setActive(bool) final;
143     void notifyClientWhenReadyForMoreSamples(const AtomicString& trackID) final;
144     bool canSwitchToType(const ContentType&) final;
145
146     void didBecomeReadyForMoreSamples(int trackID);
147     void appendCompleted();
148     void destroyParser();
149     void destroyRenderers();
150
151     void flushVideo();
152     ALLOW_NEW_API_WITHOUT_GUARDS_BEGIN
153     void flush(AVSampleBufferAudioRenderer *);
154     ALLOW_NEW_API_WITHOUT_GUARDS_END
155
156     WeakPtr<SourceBufferPrivateAVFObjC> createWeakPtr() { return m_weakFactory.createWeakPtr(*this); }
157
158     Vector<RefPtr<VideoTrackPrivateMediaSourceAVFObjC>> m_videoTracks;
159     Vector<RefPtr<AudioTrackPrivateMediaSourceAVFObjC>> m_audioTracks;
160     Vector<SourceBufferPrivateAVFObjCErrorClient*> m_errorClients;
161
162     WeakPtrFactory<SourceBufferPrivateAVFObjC> m_weakFactory;
163     WeakPtrFactory<SourceBufferPrivateAVFObjC> m_appendWeakFactory;
164
165     RetainPtr<AVStreamDataParser> m_parser;
166     RetainPtr<AVAsset> m_asset;
167     RetainPtr<AVSampleBufferDisplayLayer> m_displayLayer;
168     ALLOW_NEW_API_WITHOUT_GUARDS_BEGIN
169     HashMap<int, RetainPtr<AVSampleBufferAudioRenderer>> m_audioRenderers;
170     ALLOW_NEW_API_WITHOUT_GUARDS_END
171     RetainPtr<WebAVStreamDataParserListener> m_delegate;
172     RetainPtr<WebAVSampleBufferErrorListener> m_errorListener;
173     RetainPtr<NSError> m_hdcpError;
174     Box<BinarySemaphore> m_hasSessionSemaphore;
175     OSObjectPtr<dispatch_group_t> m_isAppendingGroup;
176     RefPtr<WebCoreDecompressionSession> m_decompressionSession;
177
178     MediaSourcePrivateAVFObjC* m_mediaSource;
179     SourceBufferPrivateClient* m_client { nullptr };
180 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
181     CDMSessionMediaSourceAVFObjC* m_session { nullptr };
182 #endif
183 #if ENABLE(ENCRYPTED_MEDIA) && HAVE(AVCONTENTKEYSESSION)
184     RefPtr<CDMInstanceFairPlayStreamingAVFObjC> m_cdmInstance;
185 #endif
186
187     std::optional<FloatSize> m_cachedSize;
188     FloatSize m_currentSize;
189     bool m_parsingSucceeded { true };
190     bool m_parserStateWasReset { false };
191     bool m_discardSamplesUntilNextInitializationSegment { false };
192     int m_enabledVideoTrackID { -1 };
193     int m_protectedTrackID { -1 };
194 };
195
196 }
197
198 #endif // ENABLE(MEDIA_SOURCE) && USE(AVFOUNDATION)