1 | /* |
2 | * Copyright (C) 2007, 2009 Apple Inc. All rights reserved. |
3 | * Copyright (C) 2007 Collabora Ltd. All rights reserved. |
4 | * Copyright (C) 2007 Alp Toker <alp@atoker.com> |
5 | * Copyright (C) 2009, 2010, 2011, 2012, 2013, 2015, 2016 Igalia S.L |
6 | * Copyright (C) 2014 Cable Television Laboratories, Inc. |
7 | * Copyright (C) 2015, 2016 Metrological Group B.V. |
8 | * |
9 | * This library is free software; you can redistribute it and/or |
10 | * modify it under the terms of the GNU Library General Public |
11 | * License as published by the Free Software Foundation; either |
12 | * version 2 of the License, or (at your option) any later version. |
13 | * |
14 | * This library is distributed in the hope that it will be useful, |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
17 | * Library General Public License for more details. |
18 | * |
19 | * You should have received a copy of the GNU Library General Public License |
20 | * aint with this library; see the file COPYING.LIB. If not, write to |
21 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
22 | * Boston, MA 02110-1301, USA. |
23 | */ |
24 | |
25 | #pragma once |
26 | |
27 | #if ENABLE(VIDEO) && USE(GSTREAMER) |
28 | |
29 | #include "GStreamerCommon.h" |
30 | #include "MediaPlayerPrivateGStreamerBase.h" |
31 | |
32 | #include <glib.h> |
33 | #include <gst/gst.h> |
34 | #include <gst/pbutils/install-plugins.h> |
35 | #include <wtf/Forward.h> |
36 | #include <wtf/RunLoop.h> |
37 | #include <wtf/WeakPtr.h> |
38 | |
39 | #if ENABLE(VIDEO_TRACK) |
40 | #include "TrackPrivateBaseGStreamer.h" |
41 | #include <wtf/text/AtomicStringHash.h> |
42 | #endif |
43 | |
44 | typedef struct _GstMpegtsSection GstMpegtsSection; |
45 | |
46 | namespace WebCore { |
47 | |
48 | #if ENABLE(WEB_AUDIO) |
49 | class AudioSourceProvider; |
50 | class AudioSourceProviderGStreamer; |
51 | #endif |
52 | |
53 | class AudioTrackPrivateGStreamer; |
54 | class InbandMetadataTextTrackPrivateGStreamer; |
55 | class InbandTextTrackPrivateGStreamer; |
56 | class MediaPlayerRequestInstallMissingPluginsCallback; |
57 | class VideoTrackPrivateGStreamer; |
58 | |
59 | #if ENABLE(MEDIA_SOURCE) |
60 | class MediaSourcePrivateClient; |
61 | #endif |
62 | |
63 | class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateGStreamerBase { |
64 | public: |
65 | explicit MediaPlayerPrivateGStreamer(MediaPlayer*); |
66 | virtual ~MediaPlayerPrivateGStreamer(); |
67 | |
68 | static void registerMediaEngine(MediaEngineRegistrar); |
69 | static bool isAvailable(); |
70 | |
71 | void handleMessage(GstMessage*); |
72 | void handlePluginInstallerResult(GstInstallPluginsReturn); |
73 | |
74 | bool hasVideo() const override { return m_hasVideo; } |
75 | bool hasAudio() const override { return m_hasAudio; } |
76 | |
77 | void load(const String &url) override; |
78 | #if ENABLE(MEDIA_SOURCE) |
79 | void load(const String& url, MediaSourcePrivateClient*) override; |
80 | #endif |
81 | #if ENABLE(MEDIA_STREAM) |
82 | void load(MediaStreamPrivate&) override; |
83 | #endif |
84 | void commitLoad(); |
85 | void cancelLoad() override; |
86 | |
87 | void prepareToPlay() override; |
88 | void play() override; |
89 | void pause() override; |
90 | |
91 | bool paused() const override; |
92 | bool seeking() const override; |
93 | |
94 | MediaTime platformDuration() const; |
95 | MediaTime durationMediaTime() const override; |
96 | MediaTime currentMediaTime() const override; |
97 | void seek(const MediaTime&) override; |
98 | |
99 | void setRate(float) override; |
100 | double rate() const override; |
101 | void setPreservesPitch(bool) override; |
102 | |
103 | void setPreload(MediaPlayer::Preload) override; |
104 | void fillTimerFired(); |
105 | |
106 | std::unique_ptr<PlatformTimeRanges> buffered() const override; |
107 | MediaTime maxMediaTimeSeekable() const override; |
108 | bool didLoadingProgress() const override; |
109 | unsigned long long totalBytes() const override; |
110 | MediaTime maxTimeLoaded() const override; |
111 | |
112 | bool hasSingleSecurityOrigin() const override; |
113 | Optional<bool> wouldTaintOrigin(const SecurityOrigin&) const override; |
114 | |
115 | void loadStateChanged(); |
116 | void timeChanged(); |
117 | void didEnd(); |
118 | virtual void durationChanged(); |
119 | void loadingFailed(MediaPlayer::NetworkState, MediaPlayer::ReadyState = MediaPlayer::HaveNothing, bool forceNotifications = false); |
120 | |
121 | virtual void sourceSetup(GstElement*); |
122 | |
123 | GstElement* audioSink() const override; |
124 | virtual void configurePlaySink() { } |
125 | |
126 | void simulateAudioInterruption() override; |
127 | |
128 | virtual bool changePipelineState(GstState); |
129 | |
130 | #if ENABLE(WEB_AUDIO) |
131 | AudioSourceProvider* audioSourceProvider() override; |
132 | #endif |
133 | |
134 | bool isLiveStream() const override { return m_isStreaming; } |
135 | |
136 | void enableTrack(TrackPrivateBaseGStreamer::TrackType, unsigned index); |
137 | |
138 | bool handleSyncMessage(GstMessage*) override; |
139 | |
140 | private: |
141 | static void getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>&); |
142 | static MediaPlayer::SupportsType supportsType(const MediaEngineSupportParameters&); |
143 | void syncOnClock(bool sync); |
144 | |
145 | GstElement* createAudioSink() override; |
146 | |
147 | MediaTime playbackPosition() const; |
148 | |
149 | virtual void updateStates(); |
150 | virtual void asyncStateChangeDone(); |
151 | |
152 | void createGSTPlayBin(const URL&, const String& pipelineName); |
153 | |
154 | bool loadNextLocation(); |
155 | void mediaLocationChanged(GstMessage*); |
156 | |
157 | virtual void setDownloadBuffering(); |
158 | void processBufferingStats(GstMessage*); |
159 | #if ENABLE(VIDEO_TRACK) |
160 | #if USE(GSTREAMER_MPEGTS) |
161 | void processMpegTsSection(GstMpegtsSection*); |
162 | #endif |
163 | |
164 | void processTableOfContents(GstMessage*); |
165 | void processTableOfContentsEntry(GstTocEntry*); |
166 | |
167 | void purgeInvalidAudioTracks(Vector<String> validTrackIds); |
168 | void purgeInvalidVideoTracks(Vector<String> validTrackIds); |
169 | void purgeInvalidTextTracks(Vector<String> validTrackIds); |
170 | #endif |
171 | virtual bool doSeek(const MediaTime& position, float rate, GstSeekFlags seekType); |
172 | virtual void updatePlaybackRate(); |
173 | |
174 | String engineDescription() const override { return "GStreamer" ; } |
175 | bool didPassCORSAccessCheck() const override; |
176 | bool canSaveMediaData() const override; |
177 | |
178 | void purgeOldDownloadFiles(const char*); |
179 | static void uriDecodeBinElementAddedCallback(GstBin*, GstElement*, MediaPlayerPrivateGStreamer*); |
180 | static void downloadBufferFileCreatedCallback(MediaPlayerPrivateGStreamer*); |
181 | |
182 | void setPlaybinURL(const URL& urlString); |
183 | void loadFull(const String& url, const String& pipelineName); |
184 | |
185 | #if GST_CHECK_VERSION(1, 10, 0) |
186 | void updateTracks(); |
187 | void clearTracks(); |
188 | #endif |
189 | |
190 | protected: |
191 | bool m_buffering; |
192 | int m_bufferingPercentage; |
193 | mutable MediaTime m_cachedPosition; |
194 | mutable MediaTime m_cachedDuration; |
195 | bool m_canFallBackToLastFinishedSeekPosition; |
196 | bool m_changingRate; |
197 | bool m_downloadFinished; |
198 | bool m_errorOccured; |
199 | mutable bool m_isEndReached; |
200 | mutable bool m_isStreaming; |
201 | bool m_paused; |
202 | float m_playbackRate; |
203 | GstState m_currentState; |
204 | GstState m_oldState; |
205 | GstState m_requestedState; |
206 | bool m_resetPipeline; |
207 | bool m_seeking; |
208 | bool m_seekIsPending; |
209 | MediaTime m_seekTime; |
210 | GRefPtr<GstElement> m_source; |
211 | bool m_volumeAndMuteInitialized; |
212 | |
213 | void readyTimerFired(); |
214 | |
215 | void notifyPlayerOfVideo(); |
216 | void notifyPlayerOfVideoCaps(); |
217 | void notifyPlayerOfAudio(); |
218 | |
219 | #if ENABLE(VIDEO_TRACK) |
220 | void notifyPlayerOfText(); |
221 | void newTextSample(); |
222 | #endif |
223 | |
224 | void ensureAudioSourceProvider(); |
225 | void setAudioStreamProperties(GObject*); |
226 | |
227 | static void setAudioStreamPropertiesCallback(MediaPlayerPrivateGStreamer*, GObject*); |
228 | |
229 | static void sourceSetupCallback(MediaPlayerPrivateGStreamer*, GstElement*); |
230 | static void videoChangedCallback(MediaPlayerPrivateGStreamer*); |
231 | static void videoSinkCapsChangedCallback(MediaPlayerPrivateGStreamer*); |
232 | static void audioChangedCallback(MediaPlayerPrivateGStreamer*); |
233 | #if ENABLE(VIDEO_TRACK) |
234 | static void textChangedCallback(MediaPlayerPrivateGStreamer*); |
235 | static GstFlowReturn newTextSampleCallback(MediaPlayerPrivateGStreamer*); |
236 | #endif |
237 | |
238 | private: |
239 | |
240 | #if ENABLE(VIDEO_TRACK) |
241 | GRefPtr<GstElement> m_textAppSink; |
242 | GRefPtr<GstPad> m_textAppSinkPad; |
243 | #endif |
244 | GstStructure* m_mediaLocations; |
245 | int m_mediaLocationCurrentIndex; |
246 | bool m_playbackRatePause; |
247 | MediaTime m_timeOfOverlappingSeek; |
248 | float m_lastPlaybackRate; |
249 | Timer m_fillTimer; |
250 | MediaTime m_maxTimeLoaded; |
251 | bool m_loadingStalled { false }; |
252 | MediaPlayer::Preload m_preload; |
253 | bool m_delayingLoad; |
254 | mutable MediaTime m_maxTimeLoadedAtLastDidLoadingProgress; |
255 | bool m_hasVideo; |
256 | bool m_hasAudio; |
257 | RunLoop::Timer<MediaPlayerPrivateGStreamer> m_readyTimerHandler; |
258 | mutable unsigned long long m_totalBytes; |
259 | URL m_url; |
260 | bool m_preservesPitch; |
261 | mutable Optional<Seconds> m_lastQueryTime; |
262 | bool m_isLegacyPlaybin; |
263 | #if GST_CHECK_VERSION(1, 10, 0) |
264 | GRefPtr<GstStreamCollection> m_streamCollection; |
265 | FloatSize naturalSize() const final; |
266 | #if ENABLE(MEDIA_STREAM) |
267 | RefPtr<MediaStreamPrivate> m_streamPrivate; |
268 | #endif // ENABLE(MEDIA_STREAM) |
269 | #endif // GST_CHECK_VERSION(1, 10, 0) |
270 | String m_currentAudioStreamId; |
271 | String m_currentVideoStreamId; |
272 | String m_currentTextStreamId; |
273 | #if ENABLE(WEB_AUDIO) |
274 | std::unique_ptr<AudioSourceProviderGStreamer> m_audioSourceProvider; |
275 | #endif |
276 | GRefPtr<GstElement> m_autoAudioSink; |
277 | GRefPtr<GstElement> m_downloadBuffer; |
278 | Vector<RefPtr<MediaPlayerRequestInstallMissingPluginsCallback>> m_missingPluginCallbacks; |
279 | #if ENABLE(VIDEO_TRACK) |
280 | HashMap<AtomicString, RefPtr<AudioTrackPrivateGStreamer>> m_audioTracks; |
281 | HashMap<AtomicString, RefPtr<InbandTextTrackPrivateGStreamer>> m_textTracks; |
282 | HashMap<AtomicString, RefPtr<VideoTrackPrivateGStreamer>> m_videoTracks; |
283 | RefPtr<InbandMetadataTextTrackPrivateGStreamer> m_chaptersTrack; |
284 | #if USE(GSTREAMER_MPEGTS) |
285 | HashMap<AtomicString, RefPtr<InbandMetadataTextTrackPrivateGStreamer>> m_metadataTracks; |
286 | #endif |
287 | #endif |
288 | virtual bool isMediaSource() const { return false; } |
289 | |
290 | uint64_t m_httpResponseTotalSize { 0 }; |
291 | uint64_t m_networkReadPosition { 0 }; |
292 | mutable uint64_t m_readPositionAtLastDidLoadingProgress { 0 }; |
293 | |
294 | HashSet<RefPtr<WebCore::SecurityOrigin>> m_origins; |
295 | Optional<bool> m_hasTaintedOrigin { WTF::nullopt }; |
296 | }; |
297 | |
298 | } |
299 | |
300 | #endif // USE(GSTREAMER) |
301 | |