Title: [211864] releases/WebKitGTK/webkit-2.14/Source/WebCore
Revision
211864
Author
[email protected]
Date
2017-02-08 03:49:24 -0800 (Wed, 08 Feb 2017)

Log Message

Merge r211627 - [GStreamer] Store preloaded media in webkit's cache
https://bugs.webkit.org/show_bug.cgi?id=119477

Reviewed by Xabier Rodriguez-Calvar.

Files cached on disk by MediaPlayerPrivateGStreamer are deleted only when the player is closed. If the
WebProcess crashed, they're just left there in the cache directory. This patch changes the location
of those temporary files to a proper temporary directory (/var/tmp, as those files aren't actually
reusable, so they don't belong to a cache directory, and /tmp is a bad place because it's RAM-based on
some distros), unlinks (deletes) them right after creation and also deletes any other stalled temporary
file on the old legacy cache directory.

There's no API in GstPlaybin to control the temporary file location, so we do it manually by locating
the GstDownloadBuffer element in the pipeline as soon as it's created, reconfiguring it with the right
temporary file path and deleting the file as soon as it's created.

* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
(WebCore::MediaPlayerPrivateGStreamer::~MediaPlayerPrivateGStreamer): Stop listening to element-added.
(WebCore::MediaPlayerPrivateGStreamer::uriDecodeBinElementAddedCallback): Look for GstDownloadBuffer.
(WebCore::MediaPlayerPrivateGStreamer::downloadBufferFileCreatedCallback): Remove the file after creation.
(WebCore::MediaPlayerPrivateGStreamer::purgeOldDownloadFiles): Delete legacy files.
(WebCore::MediaPlayerPrivateGStreamer::sourceChanged): Listen to element-added signals on GstUriDecodeBin.
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h: New reference to GstDownloadBuffer.

Modified Paths

Diff

Modified: releases/WebKitGTK/webkit-2.14/Source/WebCore/ChangeLog (211863 => 211864)


--- releases/WebKitGTK/webkit-2.14/Source/WebCore/ChangeLog	2017-02-08 11:11:02 UTC (rev 211863)
+++ releases/WebKitGTK/webkit-2.14/Source/WebCore/ChangeLog	2017-02-08 11:49:24 UTC (rev 211864)
@@ -1,3 +1,29 @@
+2017-02-03  Enrique Ocaña González  <[email protected]>
+
+        [GStreamer] Store preloaded media in webkit's cache
+        https://bugs.webkit.org/show_bug.cgi?id=119477
+
+        Reviewed by Xabier Rodriguez-Calvar.
+
+        Files cached on disk by MediaPlayerPrivateGStreamer are deleted only when the player is closed. If the
+        WebProcess crashed, they're just left there in the cache directory. This patch changes the location
+        of those temporary files to a proper temporary directory (/var/tmp, as those files aren't actually
+        reusable, so they don't belong to a cache directory, and /tmp is a bad place because it's RAM-based on
+        some distros), unlinks (deletes) them right after creation and also deletes any other stalled temporary
+        file on the old legacy cache directory.
+
+        There's no API in GstPlaybin to control the temporary file location, so we do it manually by locating
+        the GstDownloadBuffer element in the pipeline as soon as it's created, reconfiguring it with the right
+        temporary file path and deleting the file as soon as it's created.
+
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
+        (WebCore::MediaPlayerPrivateGStreamer::~MediaPlayerPrivateGStreamer): Stop listening to element-added.
+        (WebCore::MediaPlayerPrivateGStreamer::uriDecodeBinElementAddedCallback): Look for GstDownloadBuffer.
+        (WebCore::MediaPlayerPrivateGStreamer::downloadBufferFileCreatedCallback): Remove the file after creation.
+        (WebCore::MediaPlayerPrivateGStreamer::purgeOldDownloadFiles): Delete legacy files.
+        (WebCore::MediaPlayerPrivateGStreamer::sourceChanged): Listen to element-added signals on GstUriDecodeBin.
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h: New reference to GstDownloadBuffer.
+
 2017-01-26  Enrique Ocaña González  <[email protected]>
 
         [GStreamer] ASSERTION FAILED: !g_object_is_floating(ptr) in adoptGRef(GstContext* ptr)

Modified: releases/WebKitGTK/webkit-2.14/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp (211863 => 211864)


--- releases/WebKitGTK/webkit-2.14/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp	2017-02-08 11:11:02 UTC (rev 211863)
+++ releases/WebKitGTK/webkit-2.14/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp	2017-02-08 11:49:24 UTC (rev 211864)
@@ -27,6 +27,7 @@
 
 #if ENABLE(VIDEO) && USE(GSTREAMER)
 
+#include "FileSystem.h"
 #include "GStreamerUtilities.h"
 #include "URL.h"
 #include "MIMETypeRegistry.h"
@@ -36,6 +37,7 @@
 #include "SecurityOrigin.h"
 #include "TimeRanges.h"
 #include "WebKitWebSourceGStreamer.h"
+#include <glib.h>
 #include <gst/gst.h>
 #include <gst/pbutils/missing-plugins.h>
 #include <limits>
@@ -195,6 +197,9 @@
         m_mediaLocations = 0;
     }
 
+    if (WEBKIT_IS_WEB_SRC(m_source.get()) && GST_OBJECT_PARENT(m_source.get()))
+        g_signal_handlers_disconnect_by_func(GST_ELEMENT_PARENT(m_source.get()), reinterpret_cast<gpointer>(uriDecodeBinElementAddedCallback), this);
+
     if (m_autoAudioSink)
         g_signal_handlers_disconnect_by_func(G_OBJECT(m_autoAudioSink.get()),
             reinterpret_cast<gpointer>(setAudioStreamPropertiesCallback), this);
@@ -1303,13 +1308,75 @@
     player->sourceChanged();
 }
 
+void MediaPlayerPrivateGStreamer::uriDecodeBinElementAddedCallback(GstBin* bin, GstElement* element, MediaPlayerPrivateGStreamer* player)
+{
+    if (g_strcmp0(G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(G_OBJECT(element))), "GstDownloadBuffer"))
+        return;
+
+    player->m_downloadBuffer = element;
+    g_signal_handlers_disconnect_by_func(bin, reinterpret_cast<gpointer>(uriDecodeBinElementAddedCallback), player);
+    g_signal_connect_swapped(element, "notify::temp-location", G_CALLBACK(downloadBufferFileCreatedCallback), player);
+
+    GUniqueOutPtr<char> oldDownloadTemplate;
+    g_object_get(element, "temp-template", &oldDownloadTemplate.outPtr(), nullptr);
+
+    GUniquePtr<char> newDownloadTemplate(g_build_filename(G_DIR_SEPARATOR_S, "var", "tmp", "WebKit-Media-XXXXXX", nullptr));
+    g_object_set(element, "temp-template", newDownloadTemplate.get(), nullptr);
+    GST_TRACE("Reconfigured file download template from '%s' to '%s'", oldDownloadTemplate.get(), newDownloadTemplate.get());
+
+    player->purgeOldDownloadFiles(oldDownloadTemplate.get());
+}
+
+void MediaPlayerPrivateGStreamer::downloadBufferFileCreatedCallback(MediaPlayerPrivateGStreamer* player)
+{
+    ASSERT(player->m_downloadBuffer);
+
+    g_signal_handlers_disconnect_by_func(player->m_downloadBuffer.get(), reinterpret_cast<gpointer>(downloadBufferFileCreatedCallback), player);
+
+    GUniqueOutPtr<char> downloadFile;
+    g_object_get(player->m_downloadBuffer.get(), "temp-location", &downloadFile.outPtr(), nullptr);
+    player->m_downloadBuffer = nullptr;
+
+    if (UNLIKELY(!deleteFile(downloadFile.get()))) {
+        GST_WARNING("Couldn't unlink media temporary file %s after creation", downloadFile.get());
+        return;
+    }
+
+    GST_TRACE("Unlinked media temporary file %s after creation", downloadFile.get());
+}
+
+void MediaPlayerPrivateGStreamer::purgeOldDownloadFiles(const char* downloadFileTemplate)
+{
+    if (!downloadFileTemplate)
+        return;
+
+    GUniquePtr<char> templatePath(g_path_get_dirname(downloadFileTemplate));
+    GUniquePtr<char> templateFile(g_path_get_basename(downloadFileTemplate));
+    String templatePattern = String(templateFile.get()).replace("X", "?");
+
+    for (auto& filePath : listDirectory(templatePath.get(), templatePattern)) {
+        if (UNLIKELY(!deleteFile(filePath))) {
+            GST_WARNING("Couldn't unlink legacy media temporary file: %s", filePath.utf8().data());
+            continue;
+        }
+
+        GST_TRACE("Unlinked legacy media temporary file: %s", filePath.utf8().data());
+    }
+}
+
 void MediaPlayerPrivateGStreamer::sourceChanged()
 {
+    if (WEBKIT_IS_WEB_SRC(m_source.get()) && GST_OBJECT_PARENT(m_source.get()))
+        g_signal_handlers_disconnect_by_func(GST_ELEMENT_PARENT(m_source.get()), reinterpret_cast<gpointer>(uriDecodeBinElementAddedCallback), this);
+
     m_source.clear();
     g_object_get(m_pipeline.get(), "source", &m_source.outPtr(), nullptr);
 
-    if (WEBKIT_IS_WEB_SRC(m_source.get()))
+    if (WEBKIT_IS_WEB_SRC(m_source.get())) {
         webKitWebSrcSetMediaPlayer(WEBKIT_WEB_SRC(m_source.get()), m_player);
+        g_signal_connect(GST_ELEMENT_PARENT(m_source.get()), "element-added", G_CALLBACK(uriDecodeBinElementAddedCallback), this);
+    }
+
 #if ENABLE(MEDIA_SOURCE)
     if (m_mediaSource && WEBKIT_IS_MEDIA_SRC(m_source.get())) {
         MediaSourceGStreamer::open(m_mediaSource.get(), WEBKIT_MEDIA_SRC(m_source.get()));

Modified: releases/WebKitGTK/webkit-2.14/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h (211863 => 211864)


--- releases/WebKitGTK/webkit-2.14/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h	2017-02-08 11:11:02 UTC (rev 211863)
+++ releases/WebKitGTK/webkit-2.14/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h	2017-02-08 11:49:24 UTC (rev 211864)
@@ -170,6 +170,10 @@
     MediaTime totalFrameDelay() override { return MediaTime::zeroTime(); }
 #endif
 
+    void purgeOldDownloadFiles(const char*);
+    static void uriDecodeBinElementAddedCallback(GstBin*, GstElement*, MediaPlayerPrivateGStreamer*);
+    static void downloadBufferFileCreatedCallback(MediaPlayerPrivateGStreamer*);
+
     void readyTimerFired();
 
     void notifyPlayerOfVideo();
@@ -238,6 +242,7 @@
 #endif
     GstState m_requestedState;
     GRefPtr<GstElement> m_autoAudioSink;
+    GRefPtr<GstElement> m_downloadBuffer;
     RefPtr<MediaPlayerRequestInstallMissingPluginsCallback> m_missingPluginsCallback;
 #if ENABLE(VIDEO_TRACK)
     Vector<RefPtr<AudioTrackPrivateGStreamer>> m_audioTracks;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to