⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 244109 in webkit


Ignore:
Timestamp:
Apr 10, 2019, 2:14:18 AM (7 years ago)
Author:
Philippe Normand
Message:

[GStreamer] Adaptive streaming playback broken with GStreamer < 1.12
https://bugs.webkit.org/show_bug.cgi?id=196765

Reviewed by Xabier Rodriguez-Calvar.

Without the following patch in gst-plugins-bad, the uridownloader
doesn't relay need-context messages to its parent, so in our case
the player can't share its context with secondary webkitwebsrc
elements and a RELEASE_ASSERT is hit in the WebProcess.

So the workaround is to use again webkit+ protocol prefixes for
GStreamer versions older than 1.12.

https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/commit/8cf858fb27919e1d631223375f81b98055623733

  • platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:

(WebCore::convertToInternalProtocol):
(WebCore::MediaPlayerPrivateGStreamer::setPlaybinURL):
(WebCore::MediaPlayerPrivateGStreamer::loadFull):
(WebCore::MediaPlayerPrivateGStreamer::handleMessage):
(WebCore::MediaPlayerPrivateGStreamer::wouldTaintOrigin const):

  • platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
  • platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp:

(webKitWebSrcStart):
(webKitWebSrcGetProtocols):
(convertPlaybinURI):
(webKitWebSrcSetUri):
(CachedResourceStreamingClient::responseReceived):
(webKitSrcWouldTaintOrigin):

  • platform/graphics/gstreamer/WebKitWebSourceGStreamer.h:
Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r244107 r244109  
     12019-04-10  Philippe Normand  <pnormand@igalia.com>
     2
     3        [GStreamer] Adaptive streaming playback broken with GStreamer < 1.12
     4        https://bugs.webkit.org/show_bug.cgi?id=196765
     5
     6        Reviewed by Xabier Rodriguez-Calvar.
     7
     8        Without the following patch in gst-plugins-bad, the uridownloader
     9        doesn't relay need-context messages to its parent, so in our case
     10        the player can't share its context with secondary webkitwebsrc
     11        elements and a RELEASE_ASSERT is hit in the WebProcess.
     12
     13        So the workaround is to use again webkit+ protocol prefixes for
     14        GStreamer versions older than 1.12.
     15
     16        https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/commit/8cf858fb27919e1d631223375f81b98055623733
     17
     18        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
     19        (WebCore::convertToInternalProtocol):
     20        (WebCore::MediaPlayerPrivateGStreamer::setPlaybinURL):
     21        (WebCore::MediaPlayerPrivateGStreamer::loadFull):
     22        (WebCore::MediaPlayerPrivateGStreamer::handleMessage):
     23        (WebCore::MediaPlayerPrivateGStreamer::wouldTaintOrigin const):
     24        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
     25        * platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp:
     26        (webKitWebSrcStart):
     27        (webKitWebSrcGetProtocols):
     28        (convertPlaybinURI):
     29        (webKitWebSrcSetUri):
     30        (CachedResourceStreamingClient::responseReceived):
     31        (webKitSrcWouldTaintOrigin):
     32        * platform/graphics/gstreamer/WebKitWebSourceGStreamer.h:
     33
    1342019-04-10  Carlos Garcia Campos  <cgarcia@igalia.com>
    235
  • trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp

    r244074 r244109  
    226226}
    227227
     228static void convertToInternalProtocol(URL& url)
     229{
     230    if (webkitGstCheckVersion(1, 12, 0))
     231        return;
     232    if (url.protocolIsInHTTPFamily() || url.protocolIsBlob())
     233        url.setProtocol("webkit+" + url.protocol());
     234}
     235
    228236void MediaPlayerPrivateGStreamer::setPlaybinURL(const URL& url)
    229237{
     
    234242
    235243    m_url = URL(URL(), cleanURLString);
     244    convertToInternalProtocol(m_url);
    236245    GST_INFO_OBJECT(pipeline(), "Load %s", m_url.string().utf8().data());
    237246    g_object_set(m_pipeline.get(), "uri", m_url.string().utf8().data(), nullptr);
     
    303312    m_player->readyStateChanged();
    304313    m_volumeAndMuteInitialized = false;
     314    m_hasTaintedOrigin = WTF::nullopt;
    305315
    306316    if (!m_delayingLoad)
     
    13501360            if (uri) {
    13511361                URL url(URL(), uri);
    1352 
     1362                convertToInternalProtocol(url);
    13531363                m_origins.add(SecurityOrigin::create(url));
    13541364
     
    13621372                const char* contentLengthHeaderName = httpHeaderNameString(HTTPHeaderName::ContentLength).utf8().data();
    13631373                uint64_t contentLength = 0;
    1364                 gst_structure_get_uint64(responseHeaders.get(), contentLengthHeaderName, &contentLength);
     1374                if (!gst_structure_get_uint64(responseHeaders.get(), contentLengthHeaderName, &contentLength)) {
     1375                    // souphttpsrc sets a string for Content-Length, so
     1376                    // handle it here, until we remove the webkit+ protocol
     1377                    // prefix from webkitwebsrc.
     1378                    if (const char* contentLengthAsString = gst_structure_get_string(responseHeaders.get(), contentLengthHeaderName)) {
     1379                        contentLength = g_ascii_strtoull(contentLengthAsString, nullptr, 10);
     1380                        if (contentLength == G_MAXUINT64)
     1381                            contentLength = 0;
     1382                    }
     1383                }
    13651384                GST_INFO_OBJECT(pipeline(), "%s stream detected", !contentLength ? "Live" : "Non-live");
    13661385                if (!contentLength) {
     
    13721391            if (gst_structure_get(structure, "read-position", G_TYPE_UINT64, &m_networkReadPosition, "size", G_TYPE_UINT64, &m_httpResponseTotalSize, nullptr))
    13731392                GST_DEBUG_OBJECT(pipeline(), "Updated network read position %" G_GUINT64_FORMAT ", size: %" G_GUINT64_FORMAT, m_networkReadPosition, m_httpResponseTotalSize);
     1393        } else if (gst_structure_has_name(structure, "adaptive-streaming-statistics")) {
     1394            if (WEBKIT_IS_WEB_SRC(m_source.get()) && !webkitGstCheckVersion(1, 12, 0)) {
     1395                if (const char* uri = gst_structure_get_string(structure, "uri"))
     1396                    m_hasTaintedOrigin = webKitSrcWouldTaintOrigin(WEBKIT_WEB_SRC(m_source.get()), SecurityOrigin::create(URL(URL(), uri)));
     1397            }
    13741398        } else
    13751399            GST_DEBUG_OBJECT(pipeline(), "Unhandled element message: %" GST_PTR_FORMAT, structure);
     
    24902514Optional<bool> MediaPlayerPrivateGStreamer::wouldTaintOrigin(const SecurityOrigin& origin) const
    24912515{
    2492     GST_TRACE_OBJECT(pipeline(), "Checking %u origins", m_origins.size());
    2493     for (auto& responseOrigin : m_origins) {
    2494         if (!origin.canAccess(*responseOrigin)) {
    2495             GST_DEBUG_OBJECT(pipeline(), "Found reachable response origin");
    2496             return true;
    2497         }
    2498     }
    2499     GST_DEBUG_OBJECT(pipeline(), "No valid response origin found");
    2500     return false;
     2516    if (webkitGstCheckVersion(1, 12, 0)) {
     2517        GST_TRACE_OBJECT(pipeline(), "Checking %u origins", m_origins.size());
     2518        for (auto& responseOrigin : m_origins) {
     2519            if (!origin.canAccess(*responseOrigin)) {
     2520                GST_DEBUG_OBJECT(pipeline(), "Found reachable response origin");
     2521                return true;
     2522            }
     2523        }
     2524        GST_DEBUG_OBJECT(pipeline(), "No valid response origin found");
     2525        return false;
     2526    }
     2527
     2528    // GStreamer < 1.12 has an incomplete uridownloader implementation so we
     2529    // can't use WebKitWebSrc for adaptive fragments downloading if this
     2530    // version is detected.
     2531    UNUSED_PARAM(origin);
     2532    return m_hasTaintedOrigin;
    25012533}
    25022534
  • trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h

    r243537 r244109  
    293293
    294294    HashSet<RefPtr<WebCore::SecurityOrigin>> m_origins;
     295    Optional<bool> m_hasTaintedOrigin { WTF::nullopt };
    295296};
    296297
  • trunk/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp

    r243603 r244109  
    4545    virtual ~CachedResourceStreamingClient();
    4646
     47    const HashSet<RefPtr<WebCore::SecurityOrigin>>& securityOrigins() const { return m_origins; }
     48
    4749private:
    4850    void checkUpdateBlocksize(uint64_t bytesRead);
     
    6668    GRefPtr<GstElement> m_src;
    6769    ResourceRequest m_request;
     70    HashSet<RefPtr<WebCore::SecurityOrigin>> m_origins;
    6871};
    6972
     
    487490    WebKitWebSrcPrivate* priv = src->priv;
    488491
    489     if (!priv->player) {
     492    if (webkitGstCheckVersion(1, 12, 0) && !priv->player) {
    490493        GRefPtr<GstQuery> query = adoptGRef(gst_query_new_context(WEBKIT_WEB_SRC_PLAYER_CONTEXT_TYPE_NAME));
    491494        if (gst_pad_peer_query(GST_BASE_SRC_PAD(baseSrc), query.get())) {
     
    766769const gchar* const* webKitWebSrcGetProtocols(GType)
    767770{
    768     static const char* protocols[] = {"http", "https", "blob", nullptr };
     771    static const char* protocols[4];
     772    if (webkitGstCheckVersion(1, 12, 0)) {
     773        protocols[0] = "http";
     774        protocols[1] = "https";
     775        protocols[2] = "blob";
     776    } else {
     777        protocols[0] = "webkit+http";
     778        protocols[1] = "webkit+https";
     779        protocols[2] = "webkit+blob";
     780    }
     781    protocols[3] = nullptr;
    769782    return protocols;
     783}
     784
     785static URL convertPlaybinURI(const char* uriString)
     786{
     787    URL url(URL(), uriString);
     788    if (!webkitGstCheckVersion(1, 12, 0)) {
     789        ASSERT(url.protocol().substring(0, 7) == "webkit+");
     790        url.setProtocol(url.protocol().substring(7).toString());
     791    }
     792    return url;
    770793}
    771794
     
    797820    }
    798821
    799     URL url(URL(), uri);
     822    URL url = convertPlaybinURI(uri);
     823
    800824    if (!urlHasSupportedProtocol(url)) {
    801825        g_set_error(error, GST_URI_ERROR, GST_URI_ERROR_BAD_URI, "Invalid URI '%s'", uri);
     
    879903
    880904    GST_DEBUG_OBJECT(src, "Received response: %d", response.httpStatusCode());
     905
     906    m_origins.add(SecurityOrigin::create(response.url()));
    881907
    882908    auto responseURI = response.url().string().utf8();
     
    10631089}
    10641090
     1091bool webKitSrcWouldTaintOrigin(WebKitWebSrc* src, const SecurityOrigin& origin)
     1092{
     1093    WebKitWebSrcPrivate* priv = src->priv;
     1094
     1095    auto* cachedResourceStreamingClient = reinterpret_cast<CachedResourceStreamingClient*>(priv->resource->client());
     1096    for (auto& responseOrigin : cachedResourceStreamingClient->securityOrigins()) {
     1097        if (!origin.canAccess(*responseOrigin))
     1098            return true;
     1099    }
     1100    return false;
     1101}
     1102
    10651103#endif // ENABLE(VIDEO) && USE(GSTREAMER)
  • trunk/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.h

    r243197 r244109  
    2626namespace WebCore {
    2727class MediaPlayer;
     28class SecurityOrigin;
    2829}
    2930
     
    5556void webKitWebSrcSetMediaPlayer(WebKitWebSrc*, WebCore::MediaPlayer*);
    5657bool webKitSrcPassedCORSAccessCheck(WebKitWebSrc*);
     58bool webKitSrcWouldTaintOrigin(WebKitWebSrc*, const WebCore::SecurityOrigin&);
    5759
    5860G_END_DECLS
Note: See TracChangeset for help on using the changeset viewer.