[GStreamer] AppendPipeline: support dispatch of decryption-specific GstStructure...
[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 "GRefPtrGStreamer.h"
26 #include "GUniquePtrGStreamer.h"
27 #include "MediaPlayerPrivateGStreamerMSE.h"
28 #include "MediaSourceClientGStreamerMSE.h"
29 #include "SourceBufferPrivateGStreamer.h"
30
31 #include <gst/gst.h>
32 #include <wtf/Condition.h>
33
34 namespace WebCore {
35
36 #if !LOG_DISABLED
37 struct PadProbeInformation {
38     AppendPipeline* appendPipeline;
39     const char* description;
40     gulong probeId;
41 };
42 #endif
43
44 class AppendPipeline : public ThreadSafeRefCounted<AppendPipeline> {
45 public:
46     enum class AppendState { Invalid, NotStarted, Ongoing, KeyNegotiation, DataStarve, Sampling, LastSample, Aborting };
47
48     AppendPipeline(Ref<MediaSourceClientGStreamerMSE>, Ref<SourceBufferPrivateGStreamer>, MediaPlayerPrivateGStreamerMSE&);
49     virtual ~AppendPipeline();
50
51     void handleNeedContextSyncMessage(GstMessage*);
52     void handleApplicationMessage(GstMessage*);
53
54     gint id();
55     AppendState appendState() { return m_appendState; }
56     void setAppendState(AppendState);
57
58     GstFlowReturn handleNewAppsinkSample(GstElement*);
59     GstFlowReturn pushNewBuffer(GstBuffer*);
60 #if ENABLE(ENCRYPTED_MEDIA)
61     void dispatchDecryptionStructure(GUniquePtr<GstStructure>&&);
62 #endif
63
64     // Takes ownership of caps.
65     void parseDemuxerSrcPadCaps(GstCaps*);
66     void appsinkCapsChanged();
67     void appsinkNewSample(GstSample*);
68     void appsinkEOS();
69     void didReceiveInitializationSegment();
70     AtomicString trackId();
71     void abort();
72
73     void clearPlayerPrivate();
74     Ref<SourceBufferPrivateGStreamer> sourceBufferPrivate() { return m_sourceBufferPrivate.get(); }
75     GstBus* bus() { return m_bus.get(); }
76     GstElement* pipeline() { return m_pipeline.get(); }
77     GstElement* appsrc() { return m_appsrc.get(); }
78     GstElement* appsink() { return m_appsink.get(); }
79     GstCaps* demuxerSrcPadCaps() { return m_demuxerSrcPadCaps.get(); }
80     GstCaps* appsinkCaps() { return m_appsinkCaps.get(); }
81     RefPtr<WebCore::TrackPrivateBase> track() { return m_track; }
82     WebCore::MediaSourceStreamTypeGStreamer streamType() { return m_streamType; }
83
84     void disconnectDemuxerSrcPadFromAppsinkFromAnyThread(GstPad*);
85     void connectDemuxerSrcPadToAppsinkFromAnyThread(GstPad*);
86     void connectDemuxerSrcPadToAppsink(GstPad*);
87
88     void reportAppsrcAtLeastABufferLeft();
89     void reportAppsrcNeedDataReceived();
90
91 private:
92     void resetPipeline();
93     void checkEndOfAppend();
94     void handleAppsrcAtLeastABufferLeft();
95     void handleAppsrcNeedDataReceived();
96     void removeAppsrcDataLeavingProbe();
97     void setAppsrcDataLeavingProbe();
98 #if ENABLE(ENCRYPTED_MEDIA)
99     void dispatchPendingDecryptionStructure();
100 #endif
101
102     Ref<MediaSourceClientGStreamerMSE> m_mediaSourceClient;
103     Ref<SourceBufferPrivateGStreamer> m_sourceBufferPrivate;
104     MediaPlayerPrivateGStreamerMSE* m_playerPrivate;
105
106     // (m_mediaType, m_id) is unique.
107     gint m_id;
108
109     MediaTime m_initialDuration;
110
111     GstFlowReturn m_flowReturn;
112
113     GRefPtr<GstElement> m_pipeline;
114     GRefPtr<GstBus> m_bus;
115     GRefPtr<GstElement> m_appsrc;
116     GRefPtr<GstElement> m_demux;
117 #if ENABLE(ENCRYPTED_MEDIA)
118     GRefPtr<GstElement> m_decryptor;
119 #endif
120     // The demuxer has one src stream only, so only one appsink is needed and linked to it.
121     GRefPtr<GstElement> m_appsink;
122
123     Lock m_newSampleLock;
124     Condition m_newSampleCondition;
125     Lock m_padAddRemoveLock;
126     Condition m_padAddRemoveCondition;
127
128     GRefPtr<GstCaps> m_appsinkCaps;
129     GRefPtr<GstCaps> m_demuxerSrcPadCaps;
130     FloatSize m_presentationSize;
131
132     bool m_appsrcAtLeastABufferLeft;
133     bool m_appsrcNeedDataReceived;
134
135     gulong m_appsrcDataLeavingProbeId;
136 #if !LOG_DISABLED
137     struct PadProbeInformation m_demuxerDataEnteringPadProbeInformation;
138     struct PadProbeInformation m_appsinkDataEnteringPadProbeInformation;
139 #endif
140
141     // Keeps track of the states of append processing, to avoid performing actions inappropriate for the current state
142     // (eg: processing more samples when the last one has been detected, etc.). See setAppendState() for valid
143     // transitions.
144     AppendState m_appendState;
145
146     // Aborts can only be completed when the normal sample detection has finished. Meanwhile, the willing to abort is
147     // expressed in this field.
148     bool m_abortPending;
149
150     WebCore::MediaSourceStreamTypeGStreamer m_streamType;
151     RefPtr<WebCore::TrackPrivateBase> m_oldTrack;
152     RefPtr<WebCore::TrackPrivateBase> m_track;
153
154     GRefPtr<GstBuffer> m_pendingBuffer;
155 #if ENABLE(ENCRYPTED_MEDIA)
156     GUniquePtr<GstStructure> m_pendingDecryptionStructure;
157 #endif
158 };
159
160 } // namespace WebCore.
161
162 #endif // USE(GSTREAMER)