/
AppendPipeline.h
152 lines (121 loc) · 5.04 KB
/
AppendPipeline.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
* Copyright (C) 2016 Metrological Group B.V.
* Copyright (C) 2016 Igalia S.L
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* aint with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#pragma once
#if ENABLE(VIDEO) && USE(GSTREAMER) && ENABLE(MEDIA_SOURCE)
#include "GRefPtrGStreamer.h"
#include "MediaPlayerPrivateGStreamerMSE.h"
#include "MediaSourceClientGStreamerMSE.h"
#include "SourceBufferPrivateGStreamer.h"
#include <gst/gst.h>
#include <wtf/Condition.h>
namespace WebCore {
#if !LOG_DISABLED
struct PadProbeInformation {
AppendPipeline* appendPipeline;
const char* description;
gulong probeId;
};
#endif
class AppendPipeline : public ThreadSafeRefCounted<AppendPipeline> {
public:
enum class AppendState { Invalid, NotStarted, Ongoing, KeyNegotiation, DataStarve, Sampling, LastSample, Aborting };
AppendPipeline(Ref<MediaSourceClientGStreamerMSE>, Ref<SourceBufferPrivateGStreamer>, MediaPlayerPrivateGStreamerMSE&);
virtual ~AppendPipeline();
void handleNeedContextSyncMessage(GstMessage*);
void handleApplicationMessage(GstMessage*);
gint id();
AppendState appendState() { return m_appendState; }
void setAppendState(AppendState);
GstFlowReturn handleNewAppsinkSample(GstElement*);
GstFlowReturn pushNewBuffer(GstBuffer*);
// Takes ownership of caps.
void parseDemuxerSrcPadCaps(GstCaps*);
void appsinkCapsChanged();
void appsinkNewSample(GstSample*);
void appsinkEOS();
void didReceiveInitializationSegment();
AtomicString trackId();
void abort();
void clearPlayerPrivate();
Ref<SourceBufferPrivateGStreamer> sourceBufferPrivate() { return m_sourceBufferPrivate.get(); }
GstBus* bus() { return m_bus.get(); }
GstElement* pipeline() { return m_pipeline.get(); }
GstElement* appsrc() { return m_appsrc.get(); }
GstElement* appsink() { return m_appsink.get(); }
GstCaps* demuxerSrcPadCaps() { return m_demuxerSrcPadCaps.get(); }
GstCaps* appsinkCaps() { return m_appsinkCaps.get(); }
RefPtr<WebCore::TrackPrivateBase> track() { return m_track; }
WebCore::MediaSourceStreamTypeGStreamer streamType() { return m_streamType; }
void disconnectDemuxerSrcPadFromAppsinkFromAnyThread(GstPad*);
void connectDemuxerSrcPadToAppsinkFromAnyThread(GstPad*);
void connectDemuxerSrcPadToAppsink(GstPad*);
void reportAppsrcAtLeastABufferLeft();
void reportAppsrcNeedDataReceived();
private:
void resetPipeline();
void checkEndOfAppend();
void handleAppsrcAtLeastABufferLeft();
void handleAppsrcNeedDataReceived();
void removeAppsrcDataLeavingProbe();
void setAppsrcDataLeavingProbe();
private:
Ref<MediaSourceClientGStreamerMSE> m_mediaSourceClient;
Ref<SourceBufferPrivateGStreamer> m_sourceBufferPrivate;
MediaPlayerPrivateGStreamerMSE* m_playerPrivate;
// (m_mediaType, m_id) is unique.
gint m_id;
MediaTime m_initialDuration;
GstFlowReturn m_flowReturn;
GRefPtr<GstElement> m_pipeline;
GRefPtr<GstBus> m_bus;
GRefPtr<GstElement> m_appsrc;
GRefPtr<GstElement> m_demux;
#if ENABLE(ENCRYPTED_MEDIA)
GRefPtr<GstElement> m_decryptor;
#endif
// The demuxer has one src stream only, so only one appsink is needed and linked to it.
GRefPtr<GstElement> m_appsink;
Lock m_newSampleLock;
Condition m_newSampleCondition;
Lock m_padAddRemoveLock;
Condition m_padAddRemoveCondition;
GRefPtr<GstCaps> m_appsinkCaps;
GRefPtr<GstCaps> m_demuxerSrcPadCaps;
FloatSize m_presentationSize;
bool m_appsrcAtLeastABufferLeft;
bool m_appsrcNeedDataReceived;
gulong m_appsrcDataLeavingProbeId;
#if !LOG_DISABLED
struct PadProbeInformation m_demuxerDataEnteringPadProbeInformation;
struct PadProbeInformation m_appsinkDataEnteringPadProbeInformation;
#endif
// Keeps track of the states of append processing, to avoid performing actions inappropriate for the current state
// (eg: processing more samples when the last one has been detected, etc.). See setAppendState() for valid
// transitions.
AppendState m_appendState;
// Aborts can only be completed when the normal sample detection has finished. Meanwhile, the willing to abort is
// expressed in this field.
bool m_abortPending;
WebCore::MediaSourceStreamTypeGStreamer m_streamType;
RefPtr<WebCore::TrackPrivateBase> m_track;
GRefPtr<GstBuffer> m_pendingBuffer;
};
} // namespace WebCore.
#endif // USE(GSTREAMER)