[GStreamer][MSE] MediaSourceClientGStreamerMSE
[WebKit-https.git] / Source / WebCore / platform / graphics / gstreamer / mse / MediaSourceClientGStreamerMSE.cpp
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 #include "config.h"
22 #include "MediaSourceClientGStreamerMSE.h"
23
24 #include "AppendPipeline.h"
25 #include "MediaPlayerPrivateGStreamerMSE.h"
26 #include "WebKitMediaSourceGStreamer.h"
27
28 #if ENABLE(VIDEO) && USE(GSTREAMER) && ENABLE(MEDIA_SOURCE)
29
30 namespace WebCore {
31
32 Ref<MediaSourceClientGStreamerMSE> MediaSourceClientGStreamerMSE::create(MediaPlayerPrivateGStreamerMSE& playerPrivate)
33 {
34     ASSERT(WTF::isMainThread());
35
36     // No return adoptRef(new MediaSourceClientGStreamerMSE(playerPrivate)) because the ownership has already been transferred to MediaPlayerPrivateGStreamerMSE.
37     Ref<MediaSourceClientGStreamerMSE> client(adoptRef(*new MediaSourceClientGStreamerMSE(playerPrivate)));
38     playerPrivate.setMediaSourceClient(client.get());
39     return client;
40 }
41
42 MediaSourceClientGStreamerMSE::MediaSourceClientGStreamerMSE(MediaPlayerPrivateGStreamerMSE& playerPrivate)
43     : m_playerPrivate(&playerPrivate)
44     , m_duration(MediaTime::invalidTime())
45 {
46     ASSERT(WTF::isMainThread());
47 }
48
49 MediaSourceClientGStreamerMSE::~MediaSourceClientGStreamerMSE()
50 {
51     ASSERT(WTF::isMainThread());
52 }
53
54 MediaSourcePrivate::AddStatus MediaSourceClientGStreamerMSE::addSourceBuffer(RefPtr<SourceBufferPrivateGStreamer> sourceBufferPrivate, const ContentType&)
55 {
56     ASSERT(WTF::isMainThread());
57
58     if (!m_playerPrivate)
59         return MediaSourcePrivate::AddStatus::NotSupported;
60
61     ASSERT(m_playerPrivate->m_playbackPipeline);
62     ASSERT(sourceBufferPrivate);
63
64     RefPtr<AppendPipeline> appendPipeline = adoptRef(new AppendPipeline(*this, *sourceBufferPrivate, *m_playerPrivate));
65     GST_TRACE("Adding SourceBuffer to AppendPipeline: this=%p sourceBuffer=%p appendPipeline=%p", this, sourceBufferPrivate.get(), appendPipeline.get());
66     m_playerPrivate->m_appendPipelinesMap.add(sourceBufferPrivate, appendPipeline);
67
68     return m_playerPrivate->m_playbackPipeline->addSourceBuffer(sourceBufferPrivate);
69 }
70
71 const MediaTime& MediaSourceClientGStreamerMSE::duration()
72 {
73     ASSERT(WTF::isMainThread());
74
75     return m_duration;
76 }
77
78 void MediaSourceClientGStreamerMSE::durationChanged(const MediaTime& duration)
79 {
80     ASSERT(WTF::isMainThread());
81
82     GST_TRACE("duration: %f", duration.toFloat());
83     if (!duration.isValid() || duration.isPositiveInfinite() || duration.isNegativeInfinite())
84         return;
85
86     m_duration = duration;
87     if (m_playerPrivate)
88         m_playerPrivate->durationChanged();
89 }
90
91 void MediaSourceClientGStreamerMSE::abort(RefPtr<SourceBufferPrivateGStreamer> sourceBufferPrivate)
92 {
93     ASSERT(WTF::isMainThread());
94
95     GST_DEBUG("aborting");
96
97     if (!m_playerPrivate)
98         return;
99
100     RefPtr<AppendPipeline> appendPipeline = m_playerPrivate->m_appendPipelinesMap.get(sourceBufferPrivate);
101
102     ASSERT(appendPipeline);
103
104     appendPipeline->abort();
105 }
106
107 bool MediaSourceClientGStreamerMSE::append(RefPtr<SourceBufferPrivateGStreamer> sourceBufferPrivate, const unsigned char* data, unsigned length)
108 {
109     ASSERT(WTF::isMainThread());
110
111     GST_DEBUG("Appending %u bytes", length);
112
113     if (!m_playerPrivate)
114         return false;
115
116     RefPtr<AppendPipeline> appendPipeline = m_playerPrivate->m_appendPipelinesMap.get(sourceBufferPrivate);
117
118     ASSERT(appendPipeline);
119
120     GstBuffer* buffer = gst_buffer_new_and_alloc(length);
121     gst_buffer_fill(buffer, 0, data, length);
122
123     return appendPipeline->pushNewBuffer(buffer) == GST_FLOW_OK;
124 }
125
126 void MediaSourceClientGStreamerMSE::markEndOfStream(MediaSourcePrivate::EndOfStreamStatus status)
127 {
128     ASSERT(WTF::isMainThread());
129
130     if (!m_playerPrivate)
131         return;
132
133     m_playerPrivate->markEndOfStream(status);
134 }
135
136 void MediaSourceClientGStreamerMSE::removedFromMediaSource(RefPtr<SourceBufferPrivateGStreamer> sourceBufferPrivate)
137 {
138     ASSERT(WTF::isMainThread());
139
140     if (!m_playerPrivate)
141         return;
142
143     ASSERT(m_playerPrivate->m_playbackPipeline);
144
145     RefPtr<AppendPipeline> appendPipeline = m_playerPrivate->m_appendPipelinesMap.get(sourceBufferPrivate);
146
147     ASSERT(appendPipeline);
148
149     appendPipeline->clearPlayerPrivate();
150     m_playerPrivate->m_appendPipelinesMap.remove(sourceBufferPrivate);
151     // AppendPipeline destructor will take care of cleaning up when appropriate.
152
153     m_playerPrivate->m_playbackPipeline->removeSourceBuffer(sourceBufferPrivate);
154 }
155
156 void MediaSourceClientGStreamerMSE::flush(AtomicString trackId)
157 {
158     ASSERT(WTF::isMainThread());
159
160     if (m_playerPrivate)
161         m_playerPrivate->m_playbackPipeline->flush(trackId);
162 }
163
164 void MediaSourceClientGStreamerMSE::enqueueSample(PassRefPtr<MediaSample> prpSample)
165 {
166     ASSERT(WTF::isMainThread());
167
168     if (m_playerPrivate)
169         m_playerPrivate->m_playbackPipeline->enqueueSample(prpSample);
170 }
171
172 GRefPtr<WebKitMediaSrc> MediaSourceClientGStreamerMSE::webKitMediaSrc()
173 {
174     ASSERT(WTF::isMainThread());
175
176     if (!m_playerPrivate)
177         return nullptr;
178
179     WebKitMediaSrc* source = WEBKIT_MEDIA_SRC(m_playerPrivate->m_source.get());
180
181     ASSERT(WEBKIT_IS_MEDIA_SRC(source));
182
183     return source;
184 }
185
186 void MediaSourceClientGStreamerMSE::clearPlayerPrivate()
187 {
188     ASSERT(WTF::isMainThread());
189
190     m_playerPrivate = nullptr;
191 }
192
193 } // namespace WebCore.
194
195 #endif // USE(GSTREAMER)