Skip to content

Commit

Permalink
Merge r243197 - [GStreamer] Switch back to webkitwebsrc for adaptive …
Browse files Browse the repository at this point in the history
…streaming fragments downloading

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

Reviewed by Xabier Rodriguez-Calvar.

The webkitwebsrc element now behaves much better when used through
GStreamer's adaptivedemux, so use it for all WebKit media
downloads. The MediaPlayer needed by the webkitwebsrc element now
travels through GstContext messages and queries so that it can be
shared by multiple elements, typically the first webkitwebsrc
element downloads the HLS manifest and then adaptivedemux, through
uridownloader, will create new webkitwebsrc elements for fragments
downloading. Those new elements will query the first webkitwebsrc
element for its context.

The previous hack used to check SecurityOrigins can
also be cleaned-up. The origins are now cached upon reception of
the HTTP headers message from webkitwebsrc.

No new tests, existing http/tests/media/hls tests cover this change.

* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
(WebCore::MediaPlayerPrivateGStreamer::setPlaybinURL):
(WebCore::MediaPlayerPrivateGStreamer::loadFull):
(WebCore::MediaPlayerPrivateGStreamer::handleMessage):
(WebCore::MediaPlayerPrivateGStreamer::loadNextLocation):
(WebCore::MediaPlayerPrivateGStreamer::wouldTaintOrigin const):
(WebCore::convertToInternalProtocol): Deleted.
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp:
(WebCore::MediaPlayerPrivateGStreamerBase::handleSyncMessage):
* platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp:
(webkit_web_src_class_init):
(webKitWebSrcSetContext):
(webKitWebSrcStart):
(webKitWebSrcGetProtocols):
(webKitWebSrcSetUri):
(CachedResourceStreamingClient::responseReceived):
(convertPlaybinURI): Deleted.
(webKitSrcWouldTaintOrigin): Deleted.
* platform/graphics/gstreamer/WebKitWebSourceGStreamer.h:
  • Loading branch information
philn authored and carlosgcampos committed Apr 8, 2019
1 parent 8e31fdb commit 8198fa8
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 104 deletions.
44 changes: 44 additions & 0 deletions Source/WebCore/ChangeLog
@@ -1,3 +1,47 @@
2019-03-20 Philippe Normand <pnormand@igalia.com>

[GStreamer] Switch back to webkitwebsrc for adaptive streaming fragments downloading
https://bugs.webkit.org/show_bug.cgi?id=195948

Reviewed by Xabier Rodriguez-Calvar.

The webkitwebsrc element now behaves much better when used through
GStreamer's adaptivedemux, so use it for all WebKit media
downloads. The MediaPlayer needed by the webkitwebsrc element now
travels through GstContext messages and queries so that it can be
shared by multiple elements, typically the first webkitwebsrc
element downloads the HLS manifest and then adaptivedemux, through
uridownloader, will create new webkitwebsrc elements for fragments
downloading. Those new elements will query the first webkitwebsrc
element for its context.

The previous hack used to check SecurityOrigins can
also be cleaned-up. The origins are now cached upon reception of
the HTTP headers message from webkitwebsrc.

No new tests, existing http/tests/media/hls tests cover this change.

* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
(WebCore::MediaPlayerPrivateGStreamer::setPlaybinURL):
(WebCore::MediaPlayerPrivateGStreamer::loadFull):
(WebCore::MediaPlayerPrivateGStreamer::handleMessage):
(WebCore::MediaPlayerPrivateGStreamer::loadNextLocation):
(WebCore::MediaPlayerPrivateGStreamer::wouldTaintOrigin const):
(WebCore::convertToInternalProtocol): Deleted.
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp:
(WebCore::MediaPlayerPrivateGStreamerBase::handleSyncMessage):
* platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp:
(webkit_web_src_class_init):
(webKitWebSrcSetContext):
(webKitWebSrcStart):
(webKitWebSrcGetProtocols):
(webKitWebSrcSetUri):
(CachedResourceStreamingClient::responseReceived):
(convertPlaybinURI): Deleted.
(webKitSrcWouldTaintOrigin): Deleted.
* platform/graphics/gstreamer/WebKitWebSourceGStreamer.h:

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

REGRESSION(r243058): [GStreamer] 3 tests now timing out
Expand Down
Expand Up @@ -225,12 +225,6 @@ MediaPlayerPrivateGStreamer::~MediaPlayerPrivateGStreamer()
}
}

static void convertToInternalProtocol(URL& url)
{
if (url.protocolIsInHTTPFamily() || url.protocolIsBlob())
url.setProtocol("webkit+" + url.protocol());
}

void MediaPlayerPrivateGStreamer::setPlaybinURL(const URL& url)
{
// Clean out everything after file:// url path.
Expand All @@ -239,8 +233,6 @@ void MediaPlayerPrivateGStreamer::setPlaybinURL(const URL& url)
cleanURLString = cleanURLString.substring(0, url.pathEnd());

m_url = URL(URL(), cleanURLString);
convertToInternalProtocol(m_url);

GST_INFO_OBJECT(pipeline(), "Load %s", m_url.string().utf8().data());
g_object_set(m_pipeline.get(), "uri", m_url.string().utf8().data(), nullptr);
}
Expand Down Expand Up @@ -310,7 +302,6 @@ void MediaPlayerPrivateGStreamer::loadFull(const String& urlString, const gchar*
m_readyState = MediaPlayer::HaveNothing;
m_player->readyStateChanged();
m_volumeAndMuteInitialized = false;
m_hasTaintedOrigin = WTF::nullopt;

if (!m_delayingLoad)
commitLoad();
Expand Down Expand Up @@ -1359,9 +1350,13 @@ void MediaPlayerPrivateGStreamer::handleMessage(GstMessage* message)
}
#endif
else if (gst_structure_has_name(structure, "http-headers")) {
if (const char* uri = gst_structure_get_string(structure, "uri")) {
const char* redirectionUri = gst_structure_get_string(structure, "redirection-uri");
const char* uri = redirectionUri ? redirectionUri : gst_structure_get_string(structure, "uri");
if (uri) {
URL url(URL(), uri);
convertToInternalProtocol(url);

m_origins.add(SecurityOrigin::create(url));

if (url != m_url) {
GST_DEBUG_OBJECT(pipeline(), "Ignoring HTTP response headers for non-main URI.");
break;
Expand All @@ -1371,16 +1366,7 @@ void MediaPlayerPrivateGStreamer::handleMessage(GstMessage* message)
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_structure_get_uint64(responseHeaders.get(), contentLengthHeaderName, &contentLength);
GST_INFO_OBJECT(pipeline(), "%s stream detected", !contentLength ? "Live" : "Non-live");
if (!contentLength) {
m_isStreaming = true;
Expand All @@ -1390,10 +1376,6 @@ void MediaPlayerPrivateGStreamer::handleMessage(GstMessage* message)
} else if (gst_structure_has_name(structure, "webkit-network-statistics")) {
if (gst_structure_get_uint64(structure, "read-position", &m_networkReadPosition))
GST_DEBUG_OBJECT(pipeline(), "Updated network read position %" G_GUINT64_FORMAT, m_networkReadPosition);
} else if (gst_structure_has_name(structure, "adaptive-streaming-statistics")) {
if (WEBKIT_IS_WEB_SRC(m_source.get()))
if (const char* uri = gst_structure_get_string(structure, "uri"))
m_hasTaintedOrigin = webKitSrcWouldTaintOrigin(WEBKIT_WEB_SRC(m_source.get()), SecurityOrigin::create(URL(URL(), uri)));
} else
GST_DEBUG_OBJECT(pipeline(), "Unhandled element message: %" GST_PTR_FORMAT, structure);
break;
Expand Down Expand Up @@ -2181,7 +2163,6 @@ bool MediaPlayerPrivateGStreamer::loadNextLocation()
// append the value of new-location to it.
URL baseUrl = gst_uri_is_valid(newLocation) ? URL() : m_url;
URL newUrl = URL(baseUrl, newLocation);
convertToInternalProtocol(newUrl);

auto securityOrigin = SecurityOrigin::create(m_url);
if (securityOrigin->canRequest(newUrl)) {
Expand Down Expand Up @@ -2590,17 +2571,19 @@ bool MediaPlayerPrivateGStreamer::canSaveMediaData() const
return false;
}

Optional<bool> MediaPlayerPrivateGStreamer::wouldTaintOrigin(const SecurityOrigin&) const
Optional<bool> MediaPlayerPrivateGStreamer::wouldTaintOrigin(const SecurityOrigin& origin) const
{
// Ideally the given origin should always be verified with
// webKitSrcWouldTaintOrigin() instead of only checking it for
// adaptive-streaming-statistics. We can't do this yet because HLS fragments
// are currently downloaded independently from WebKit.
// See also https://bugs.webkit.org/show_bug.cgi?id=189967.
return m_hasTaintedOrigin;
GST_TRACE_OBJECT(pipeline(), "Checking %u origins", m_origins.size());
for (auto& responseOrigin : m_origins) {
if (!origin.canAccess(*responseOrigin)) {
GST_DEBUG_OBJECT(pipeline(), "Found reachable response origin");
return true;
}
}
GST_DEBUG_OBJECT(pipeline(), "No valid response origin found");
return false;
}


}

#endif // USE(GSTREAMER)
Expand Up @@ -290,8 +290,9 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateGStreamerBase {
uint64_t m_networkReadPosition { 0 };
mutable uint64_t m_readPositionAtLastDidLoadingProgress { 0 };

Optional<bool> m_hasTaintedOrigin { WTF::nullopt };
HashSet<RefPtr<WebCore::SecurityOrigin>> m_origins;
};

}

#endif // USE(GSTREAMER)
Expand Up @@ -36,6 +36,7 @@
#include "MediaPlayer.h"
#include "NotImplemented.h"
#include "VideoSinkGStreamer.h"
#include "WebKitWebSourceGStreamer.h"
#include <wtf/glib/GUniquePtr.h>
#include <wtf/text/AtomicString.h>
#include <wtf/text/CString.h>
Expand Down Expand Up @@ -337,6 +338,16 @@ bool MediaPlayerPrivateGStreamerBase::handleSyncMessage(GstMessage* message)
gst_message_parse_context_type(message, &contextType);
GST_DEBUG_OBJECT(pipeline(), "Handling %s need-context message for %s", contextType, GST_MESSAGE_SRC_NAME(message));

if (!g_strcmp0(contextType, WEBKIT_WEB_SRC_PLAYER_CONTEXT_TYPE_NAME)) {
GRefPtr<GstContext> context = adoptGRef(gst_context_new(WEBKIT_WEB_SRC_PLAYER_CONTEXT_TYPE_NAME, FALSE));
GstStructure* contextStructure = gst_context_writable_structure(context.get());

ASSERT(m_player);
gst_structure_set(contextStructure, "player", G_TYPE_POINTER, m_player, nullptr);
gst_element_set_context(GST_ELEMENT(GST_MESSAGE_SRC(message)), context.get());
return true;
}

#if USE(GSTREAMER_GL)
GRefPtr<GstContext> elementContext = adoptGRef(requestGLContext(contextType));
if (elementContext) {
Expand Down

0 comments on commit 8198fa8

Please sign in to comment.