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 Igalia S.L
6 * Copyright (C) 2014 Cable Television Laboratories, Inc.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public License
19 * aint with this library; see the file COPYING.LIB.  If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23
24#ifndef MediaPlayerPrivateGStreamer_h
25#define MediaPlayerPrivateGStreamer_h
26#if ENABLE(VIDEO) && USE(GSTREAMER)
27
28#include "GRefPtrGStreamer.h"
29#include "MediaPlayerPrivateGStreamerBase.h"
30#include "Timer.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/gobject/GMainLoopSource.h>
37
38#if ENABLE(VIDEO_TRACK) && USE(GSTREAMER_MPEGTS)
39#include <wtf/text/AtomicStringHash.h>
40#endif
41
42#if ENABLE(MEDIA_SOURCE)
43#include "MediaSourceGStreamer.h"
44#endif
45
46typedef struct _GstBuffer GstBuffer;
47typedef struct _GstMessage GstMessage;
48typedef struct _GstElement GstElement;
49typedef struct _GstMpegTsSection GstMpegTsSection;
50
51namespace WebCore {
52
53class AudioTrackPrivateGStreamer;
54class InbandMetadataTextTrackPrivateGStreamer;
55class InbandTextTrackPrivateGStreamer;
56class VideoTrackPrivateGStreamer;
57
58class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateGStreamerBase {
59public:
60    ~MediaPlayerPrivateGStreamer();
61    static void registerMediaEngine(MediaEngineRegistrar);
62    gboolean handleMessage(GstMessage*);
63    void handlePluginInstallerResult(GstInstallPluginsReturn);
64
65    bool hasVideo() const { return m_hasVideo; }
66    bool hasAudio() const { return m_hasAudio; }
67
68    void load(const String &url);
69#if ENABLE(MEDIA_SOURCE)
70    void load(const String& url, MediaSourcePrivateClient*);
71#endif
72    void commitLoad();
73    void cancelLoad();
74
75    void prepareToPlay();
76    void play();
77    void pause();
78
79    bool paused() const;
80    bool seeking() const;
81
82    float duration() const;
83    float currentTime() const;
84    void seek(float);
85
86    void setRate(float);
87    void setPreservesPitch(bool);
88
89    void setPreload(MediaPlayer::Preload);
90    void fillTimerFired(Timer<MediaPlayerPrivateGStreamer>*);
91
92    std::unique_ptr<PlatformTimeRanges> buffered() const;
93    float maxTimeSeekable() const;
94    bool didLoadingProgress() const;
95    unsigned totalBytes() const;
96    float maxTimeLoaded() const;
97
98    void loadStateChanged();
99    void timeChanged();
100    void didEnd();
101    void durationChanged();
102    void loadingFailed(MediaPlayer::NetworkState);
103
104    void videoChanged();
105    void videoCapsChanged();
106    void audioChanged();
107    void notifyPlayerOfVideo();
108    void notifyPlayerOfVideoCaps();
109    void notifyPlayerOfAudio();
110
111#if ENABLE(VIDEO_TRACK)
112    void textChanged();
113    void notifyPlayerOfText();
114
115    void newTextSample();
116    void notifyPlayerOfNewTextSample();
117#endif
118
119    void sourceChanged();
120    GstElement* audioSink() const;
121
122    void setAudioStreamProperties(GObject*);
123
124    void simulateAudioInterruption();
125
126    bool changePipelineState(GstState);
127
128private:
129    MediaPlayerPrivateGStreamer(MediaPlayer*);
130
131    static PassOwnPtr<MediaPlayerPrivateInterface> create(MediaPlayer*);
132
133    static void getSupportedTypes(HashSet<String>&);
134    static MediaPlayer::SupportsType supportsType(const MediaEngineSupportParameters&);
135
136    static bool isAvailable();
137
138    GstElement* createAudioSink();
139
140    float playbackPosition() const;
141
142    void cacheDuration();
143    void updateStates();
144    void asyncStateChangeDone();
145
146    void createGSTPlayBin();
147
148    bool loadNextLocation();
149    void mediaLocationChanged(GstMessage*);
150
151    void setDownloadBuffering();
152    void processBufferingStats(GstMessage*);
153#if ENABLE(VIDEO_TRACK) && USE(GSTREAMER_MPEGTS)
154    void processMpegTsSection(GstMpegTsSection*);
155#endif
156#if ENABLE(VIDEO_TRACK)
157    void processTableOfContents(GstMessage*);
158    void processTableOfContentsEntry(GstTocEntry*, GstTocEntry* parent);
159#endif
160    bool doSeek(gint64 position, float rate, GstSeekFlags seekType);
161    void updatePlaybackRate();
162
163
164    virtual String engineDescription() const { return "GStreamer"; }
165    virtual bool isLiveStream() const { return m_isStreaming; }
166    virtual bool didPassCORSAccessCheck() const;
167
168private:
169    GRefPtr<GstElement> m_playBin;
170    GRefPtr<GstElement> m_source;
171#if ENABLE(VIDEO_TRACK)
172    GRefPtr<GstElement> m_textAppSink;
173    GRefPtr<GstPad> m_textAppSinkPad;
174#endif
175    float m_seekTime;
176    bool m_changingRate;
177    float m_endTime;
178    bool m_isEndReached;
179    mutable bool m_isStreaming;
180    GstStructure* m_mediaLocations;
181    int m_mediaLocationCurrentIndex;
182    bool m_resetPipeline;
183    bool m_paused;
184    bool m_playbackRatePause;
185    bool m_seeking;
186    bool m_seekIsPending;
187    float m_timeOfOverlappingSeek;
188    bool m_canFallBackToLastFinishedSeekPosition;
189    bool m_buffering;
190    float m_playbackRate;
191    float m_lastPlaybackRate;
192    bool m_errorOccured;
193    mutable gfloat m_mediaDuration;
194    bool m_downloadFinished;
195    Timer<MediaPlayerPrivateGStreamer> m_fillTimer;
196    float m_maxTimeLoaded;
197    int m_bufferingPercentage;
198    MediaPlayer::Preload m_preload;
199    bool m_delayingLoad;
200    bool m_mediaDurationKnown;
201    mutable float m_maxTimeLoadedAtLastDidLoadingProgress;
202    bool m_volumeAndMuteInitialized;
203    bool m_hasVideo;
204    bool m_hasAudio;
205    GMainLoopSource m_audioTimerHandler;
206    GMainLoopSource m_textTimerHandler;
207    GMainLoopSource m_videoTimerHandler;
208    GMainLoopSource m_videoCapsTimerHandler;
209    GMainLoopSource m_readyTimerHandler;
210    mutable long m_totalBytes;
211    URL m_url;
212    bool m_preservesPitch;
213    GstState m_requestedState;
214    GRefPtr<GstElement> m_autoAudioSink;
215    bool m_missingPlugins;
216#if ENABLE(VIDEO_TRACK)
217    Vector<RefPtr<AudioTrackPrivateGStreamer>> m_audioTracks;
218    Vector<RefPtr<InbandTextTrackPrivateGStreamer>> m_textTracks;
219    Vector<RefPtr<VideoTrackPrivateGStreamer>> m_videoTracks;
220    RefPtr<InbandMetadataTextTrackPrivateGStreamer> m_chaptersTrack;
221#endif
222#if ENABLE(VIDEO_TRACK) && USE(GSTREAMER_MPEGTS)
223    HashMap<AtomicString, RefPtr<InbandMetadataTextTrackPrivateGStreamer>> m_metadataTracks;
224#endif
225#if ENABLE(MEDIA_SOURCE)
226    RefPtr<MediaSourcePrivateClient> m_mediaSource;
227#endif
228};
229}
230
231#endif // USE(GSTREAMER)
232#endif
233