Skip to content

Commit

Permalink
Merge r243058 - [GStreamer] Rewrite HTTP source element using pushsrc…
Browse files Browse the repository at this point in the history
… base class

https://bugs.webkit.org/show_bug.cgi?id=195631

Reviewed by Xabier Rodriguez-Calvar.

Source/WebCore:

If we want to use webkitwebsrc in adaptivedemux (HLS, DASH, etc)
we need a source element that behaves like souphttpsrc, which is
implemented using pushsrc. This rewrite might also fix some seek
issues.

No new tests, existing http/tests/media tests cover this patch.

* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
(WebCore::MediaPlayerPrivateGStreamer::handleMessage):
* platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp:
(webkit_web_src_class_init):
(webkitWebSrcReset):
(webkit_web_src_init):
(webKitWebSrcCreate):
(webKitWebSrcStart):
(webKitWebSrcCloseSession):
(webKitWebSrcStop):
(webKitWebSrcGetSize):
(webKitWebSrcIsSeekable):
(webKitWebSrcDoSeek):
(webKitWebSrcQuery):
(webKitWebSrcUnLock):
(webKitWebSrcUnLockStop):
(webKitWebSrcChangeState):
(CachedResourceStreamingClient::checkUpdateBlocksize):
(CachedResourceStreamingClient::responseReceived):
(CachedResourceStreamingClient::dataReceived):
(CachedResourceStreamingClient::accessControlCheckFailed):
(CachedResourceStreamingClient::loadFailed):
(CachedResourceStreamingClient::loadFinished):
* platform/graphics/gstreamer/WebKitWebSourceGStreamer.h:

LayoutTests:

* platform/gtk/TestExpectations:
* platform/gtk/http/tests/media/hls/video-controls-live-stream-expected.txt:
Update expectations, though it's not really related with this
patch.
  • Loading branch information
philn authored and carlosgcampos committed Apr 8, 2019
1 parent 42188ef commit b860c20
Show file tree
Hide file tree
Showing 9 changed files with 518 additions and 383 deletions.
12 changes: 12 additions & 0 deletions LayoutTests/ChangeLog
@@ -1,3 +1,15 @@
2019-03-18 Philippe Normand <pnormand@igalia.com>

[GStreamer] Rewrite HTTP source element using pushsrc base class
https://bugs.webkit.org/show_bug.cgi?id=195631

Reviewed by Xabier Rodriguez-Calvar.

* platform/gtk/TestExpectations:
* platform/gtk/http/tests/media/hls/video-controls-live-stream-expected.txt:
Update expectations, though it's not really related with this
patch.

2019-03-26 Philippe Normand <pnormand@igalia.com>

[GStreamer] Sound loop with Google Hangouts and WhatsApp notifications
Expand Down
@@ -1,3 +1,4 @@

Test that playback can be resumed by seeking backwards after load stalls.

RUN(video.play())
Expand Down
3 changes: 0 additions & 3 deletions LayoutTests/platform/gtk/TestExpectations
Expand Up @@ -2216,7 +2216,6 @@ Bug(GTK) jquery/traversing.html [ Pass Slow ]
Bug(GTK) tables/mozilla/other/slashlogo.html [ Pass Slow ]

Bug(GTK) http/tests/media/video-preload.html [ Pass Slow ]
webkit.org/b/143989 [ Release ] http/tests/media/hls/video-controls-live-stream.html [ Pass Slow Failure ]

webkit.org/b/116958 http/tests/navigation/slowmetaredirect-basic.html [ Pass Slow ]
webkit.org/b/116958 http/tests/navigation/slowtimerredirect-basic.html [ Pass Slow ]
Expand Down Expand Up @@ -2739,8 +2738,6 @@ webkit.org/b/122021 media/video-controls-captions-trackmenu.html [ Failure ]
webkit.org/b/123097 media/track/track-user-preferences.html [ Skip ]
webkit.org/b/121995 media/video-controls-captions-trackmenu-includes-enabled-track.html [ Failure ]

Bug(GTK) http/tests/media/video-play-stall-seek.html [ Skip ]

Bug(GTK) http/tests/misc/acid3.html [ Failure ]

Bug(GTK) media/video-size-intrinsic-scale.html [ Failure ]
Expand Down
@@ -1,13 +1,14 @@

EVENT(canplaythrough)
EVENT(play)
EXPECTED (video.duration == 'Infinity') OK
-webkit-media-text-track-container: classes: [hidden]
-webkit-media-controls-enclosure: classes: []
-webkit-media-controls-panel: classes: [paused]
-webkit-media-controls-panel: classes: [paused show]
-webkit-media-controls-play-button: classes: [paused]
-webkit-media-controls-timeline: classes: []
-webkit-media-controls-current-time-display: classes: [hour-long-time]
-webkit-media-controls-time-remaining-display: classes: [hidden hour-long-time]
-webkit-media-controls-time-remaining-display: classes: [hour-long-time hidden]
-webkit-media-controls-toggle-closed-captions-button: classes: [hidden]
-webkit-media-controls-fullscreen-button: classes: []
none: classes: [mute-box]
Expand Down
39 changes: 39 additions & 0 deletions Source/WebCore/ChangeLog
@@ -1,3 +1,42 @@
2019-03-18 Philippe Normand <pnormand@igalia.com>

[GStreamer] Rewrite HTTP source element using pushsrc base class
https://bugs.webkit.org/show_bug.cgi?id=195631

Reviewed by Xabier Rodriguez-Calvar.

If we want to use webkitwebsrc in adaptivedemux (HLS, DASH, etc)
we need a source element that behaves like souphttpsrc, which is
implemented using pushsrc. This rewrite might also fix some seek
issues.

No new tests, existing http/tests/media tests cover this patch.

* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
(WebCore::MediaPlayerPrivateGStreamer::handleMessage):
* platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp:
(webkit_web_src_class_init):
(webkitWebSrcReset):
(webkit_web_src_init):
(webKitWebSrcCreate):
(webKitWebSrcStart):
(webKitWebSrcCloseSession):
(webKitWebSrcStop):
(webKitWebSrcGetSize):
(webKitWebSrcIsSeekable):
(webKitWebSrcDoSeek):
(webKitWebSrcQuery):
(webKitWebSrcUnLock):
(webKitWebSrcUnLockStop):
(webKitWebSrcChangeState):
(CachedResourceStreamingClient::checkUpdateBlocksize):
(CachedResourceStreamingClient::responseReceived):
(CachedResourceStreamingClient::dataReceived):
(CachedResourceStreamingClient::accessControlCheckFailed):
(CachedResourceStreamingClient::loadFailed):
(CachedResourceStreamingClient::loadFinished):
* platform/graphics/gstreamer/WebKitWebSourceGStreamer.h:

2019-02-13 Alex Christensen <achristensen@webkit.org>

Stop using setDefersLoading from WebCore
Expand Down
18 changes: 18 additions & 0 deletions Source/WebCore/platform/graphics/gstreamer/MainThreadNotifier.h
Expand Up @@ -63,6 +63,24 @@ class MainThreadNotifier final : public ThreadSafeRefCounted<MainThreadNotifier<
});
}

template<typename F>
void notifyAndWait(T notificationType, F&& callbackFunctor)
{
Lock mutex;
Condition condition;

notify(notificationType, [functor = WTFMove(callbackFunctor), &condition, &mutex] {
functor();
LockHolder holder(mutex);
condition.notifyOne();
});

if (!isMainThread()) {
LockHolder holder(mutex);
condition.wait(mutex);
}
}

void cancelPendingNotifications(unsigned mask = 0)
{
ASSERT(m_isValid.load());
Expand Down
Expand Up @@ -546,13 +546,17 @@ void MediaPlayerPrivateGStreamer::seek(const MediaTime& mediaTime)
GST_INFO_OBJECT(pipeline(), "[Seek] seek attempt to %s", toString(mediaTime).utf8().data());

// Avoid useless seeking.
if (mediaTime == currentMediaTime())
if (mediaTime == currentMediaTime()) {
GST_DEBUG_OBJECT(pipeline(), "[Seek] seek to EOS position unhandled");
return;
}

MediaTime time = std::min(mediaTime, durationMediaTime());

if (isLiveStream())
if (isLiveStream()) {
GST_DEBUG_OBJECT(pipeline(), "[Seek] Live stream seek unhandled");
return;
}

GST_INFO_OBJECT(pipeline(), "[Seek] seeking to %s", toString(time).utf8().data());

Expand Down Expand Up @@ -1209,7 +1213,7 @@ void MediaPlayerPrivateGStreamer::handleMessage(GstMessage* message)
// We ignore state changes from internal elements. They are forwarded to playbin2 anyway.
bool messageSourceIsPlaybin = GST_MESSAGE_SRC(message) == reinterpret_cast<GstObject*>(m_pipeline.get());

GST_LOG("Message %s received from element %s", GST_MESSAGE_TYPE_NAME(message), GST_MESSAGE_SRC_NAME(message));
GST_LOG_OBJECT(pipeline(), "Message %s received from element %s", GST_MESSAGE_TYPE_NAME(message), GST_MESSAGE_SRC_NAME(message));
switch (GST_MESSAGE_TYPE(message)) {
case GST_MESSAGE_ERROR:
if (m_resetPipeline || !m_missingPluginCallbacks.isEmpty() || m_errorOccured)
Expand Down Expand Up @@ -1355,14 +1359,33 @@ void MediaPlayerPrivateGStreamer::handleMessage(GstMessage* message)
}
#endif
else if (gst_structure_has_name(structure, "http-headers")) {
GstStructure* responseHeaders;
if (gst_structure_get(structure, "response-headers", GST_TYPE_STRUCTURE, &responseHeaders, nullptr)) {
if (!gst_structure_has_field(responseHeaders, httpHeaderNameString(HTTPHeaderName::ContentLength).utf8().data())) {
GST_INFO_OBJECT(pipeline(), "Live stream detected. Disabling on-disk buffering");
if (const char* uri = gst_structure_get_string(structure, "uri")) {
URL url(URL(), uri);
convertToInternalProtocol(url);
if (url != m_url) {
GST_DEBUG_OBJECT(pipeline(), "Ignoring HTTP response headers for non-main URI.");
break;
}
}
GUniqueOutPtr<GstStructure> responseHeaders;
if (gst_structure_get(structure, "response-headers", GST_TYPE_STRUCTURE, &responseHeaders.outPtr(), nullptr)) {
const char* contentLengthHeaderName = httpHeaderNameString(HTTPHeaderName::ContentLength).utf8().data();
uint64_t contentLength = 0;
if (!gst_structure_get_uint64(responseHeaders.get(), contentLengthHeaderName, &contentLength)) {
// souphttpsrc sets a string for Content-Length, so
// handle it here, until we remove the webkit+ protocol
// prefix from webkitwebsrc.
if (const char* contentLengthAsString = gst_structure_get_string(responseHeaders.get(), contentLengthHeaderName)) {
contentLength = g_ascii_strtoull(contentLengthAsString, nullptr, 10);
if (contentLength == G_MAXUINT64)
contentLength = 0;
}
}
GST_INFO_OBJECT(pipeline(), "%s stream detected", !contentLength ? "Live" : "Non-live");
if (!contentLength) {
m_isStreaming = true;
setDownloadBuffering();
}
gst_structure_free(responseHeaders);
}
} else if (gst_structure_has_name(structure, "adaptive-streaming-statistics")) {
if (WEBKIT_IS_WEB_SRC(m_source.get()))
Expand Down Expand Up @@ -1660,9 +1683,13 @@ void MediaPlayerPrivateGStreamer::fillTimerFired()

MediaTime MediaPlayerPrivateGStreamer::maxMediaTimeSeekable() const
{
GST_TRACE_OBJECT(pipeline(), "errorOccured: %s, isLiveStream: %s", boolForPrinting(m_errorOccured), boolForPrinting(isLiveStream()));
if (m_errorOccured)
return MediaTime::zeroTime();

if (isLiveStream())
return MediaTime::zeroTime();

MediaTime duration = durationMediaTime();
GST_DEBUG_OBJECT(pipeline(), "maxMediaTimeSeekable, duration: %s", toString(duration).utf8().data());
// infinite duration means live stream
Expand Down

0 comments on commit b860c20

Please sign in to comment.