[GStreamer][EME] waitingforkey event should consider decryptors' waiting status
[WebKit-https.git] / Source / WebCore / platform / graphics / gstreamer / mse / AppendPipeline.h
1 /*
2  * Copyright (C) 2016 Metrological Group B.V.
3  * Copyright (C) 2016 Igalia S.L
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * aint with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 #pragma once
22
23 #if ENABLE(VIDEO) && USE(GSTREAMER) && ENABLE(MEDIA_SOURCE)
24
25 #include "GStreamerCommon.h"
26 #include "MediaPlayerPrivateGStreamerMSE.h"
27 #include "MediaSourceClientGStreamerMSE.h"
28 #include "SourceBufferPrivateGStreamer.h"
29
30 #include <atomic>
31 #include <gst/gst.h>
32 #include <mutex>
33 #include <wtf/Condition.h>
34 #include <wtf/Threading.h>
35
36 namespace WebCore {
37
38 #if !LOG_DISABLED || ENABLE(ENCRYPTED_MEDIA)
39 struct PadProbeInformation {
40     AppendPipeline* appendPipeline;
41     const char* description;
42     gulong probeId;
43 };
44 #endif
45
46 class AppendPipeline : public ThreadSafeRefCounted<AppendPipeline> {
47 public:
48     enum class AppendState { Invalid, NotStarted, Ongoing, DataStarve, Sampling, LastSample, Aborting };
49
50     AppendPipeline(Ref<MediaSourceClientGStreamerMSE>, Ref<SourceBufferPrivateGStreamer>, MediaPlayerPrivateGStreamerMSE&);
51     virtual ~AppendPipeline();
52
53     void handleNeedContextSyncMessage(GstMessage*);
54     void handleApplicationMessage(GstMessage*);
55     void handleStateChangeMessage(GstMessage*);
56
57     gint id();
58     AppendState appendState() { return m_appendState; }
59     void setAppendState(AppendState);
60
61     GstFlowReturn handleNewAppsinkSample(GstElement*);
62     GstFlowReturn pushNewBuffer(GstBuffer*);
63
64     // Takes ownership of caps.
65     void parseDemuxerSrcPadCaps(GstCaps*);
66     void appsinkCapsChanged();
67     void appsinkNewSample(GRefPtr<GstSample>&&);
68     void appsinkEOS();
69     void handleEndOfAppend();
70     void didReceiveInitializationSegment();
71     AtomicString trackId();
72     void abort();
73
74     void clearPlayerPrivate();
75     Ref<SourceBufferPrivateGStreamer> sourceBufferPrivate() { return m_sourceBufferPrivate.get(); }
76     GstBus* bus() { return m_bus.get(); }
77     GstElement* pipeline() { return m_pipeline.get(); }
78     GstElement* appsrc() { return m_appsrc.get(); }
79     GstElement* appsink() { return m_appsink.get(); }
80     GstCaps* demuxerSrcPadCaps() { return m_demuxerSrcPadCaps.get(); }
81     GstCaps* appsinkCaps() { return m_appsinkCaps.get(); }
82     MediaPlayerPrivateGStreamerMSE* playerPrivate() { return m_playerPrivate; }
83     RefPtr<WebCore::TrackPrivateBase> track() { return m_track; }
84     WebCore::MediaSourceStreamTypeGStreamer streamType() { return m_streamType; }
85
86     void disconnectDemuxerSrcPadFromAppsinkFromAnyThread(GstPad*);
87     void appendPipelineDemuxerNoMorePadsFromAnyThread();
88     void connectDemuxerSrcPadToAppsinkFromAnyThread(GstPad*);
89     void connectDemuxerSrcPadToAppsink(GstPad*);
90
91 private:
92     void resetPipeline();
93     void checkEndOfAppend();
94     void demuxerNoMorePads();
95
96     void consumeAppsinkAvailableSamples();
97
98     GstPadProbeReturn appsrcEndOfAppendCheckerProbe(GstPadProbeInfo*);
99
100     static void staticInitialization();
101
102     static std::once_flag s_staticInitializationFlag;
103     static GType s_endOfAppendMetaType;
104     static const GstMetaInfo* s_webKitEndOfAppendMetaInfo;
105
106     // Used only for asserting that there is only one streaming thread.
107     // Only the pointers are compared.
108     WTF::Thread* m_streamingThread;
109
110     Ref<MediaSourceClientGStreamerMSE> m_mediaSourceClient;
111     Ref<SourceBufferPrivateGStreamer> m_sourceBufferPrivate;
112     MediaPlayerPrivateGStreamerMSE* m_playerPrivate;
113
114     // (m_mediaType, m_id) is unique.
115     gint m_id;
116
117     MediaTime m_initialDuration;
118
119     GRefPtr<GstElement> m_pipeline;
120     GRefPtr<GstBus> m_bus;
121     GRefPtr<GstElement> m_appsrc;
122     GRefPtr<GstElement> m_demux;
123     GRefPtr<GstElement> m_parser; // Optional.
124     // The demuxer has one src stream only, so only one appsink is needed and linked to it.
125     GRefPtr<GstElement> m_appsink;
126
127     // Used to avoid unnecessary notifications per sample.
128     // It is read and written from the streaming thread and written from the main thread.
129     // The main thread must set it to false before actually pulling samples.
130     // This strategy ensures that at any time, there are at most two notifications in the bus
131     // queue, instead of it growing unbounded.
132     std::atomic_flag m_wasBusAlreadyNotifiedOfAvailableSamples;
133
134     Lock m_padAddRemoveLock;
135     Condition m_padAddRemoveCondition;
136
137     GRefPtr<GstCaps> m_appsinkCaps;
138     GRefPtr<GstCaps> m_demuxerSrcPadCaps;
139     FloatSize m_presentationSize;
140
141 #if !LOG_DISABLED
142     struct PadProbeInformation m_demuxerDataEnteringPadProbeInformation;
143     struct PadProbeInformation m_appsinkDataEnteringPadProbeInformation;
144 #endif
145
146 #if ENABLE(ENCRYPTED_MEDIA)
147     struct PadProbeInformation m_appsinkPadEventProbeInformation;
148 #endif
149     // Keeps track of the states of append processing, to avoid performing actions inappropriate for the current state
150     // (eg: processing more samples when the last one has been detected, etc.). See setAppendState() for valid
151     // transitions.
152     AppendState m_appendState;
153
154     // Aborts can only be completed when the normal sample detection has finished. Meanwhile, the willing to abort is
155     // expressed in this field.
156     bool m_abortPending;
157
158     WebCore::MediaSourceStreamTypeGStreamer m_streamType;
159     RefPtr<WebCore::TrackPrivateBase> m_track;
160
161     GRefPtr<GstBuffer> m_pendingBuffer;
162 };
163
164 } // namespace WebCore.
165
166 #endif // USE(GSTREAMER)