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;