Changeset 211627 in webkit


Ignore:
Timestamp:
Feb 3, 2017 4:03:10 AM (7 years ago)
Author:
eocanha@igalia.com
Message:

[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.
Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r211625 r211627  
     12017-02-03  Enrique Ocaña González  <eocanha@igalia.com>
     2
     3        [GStreamer] Store preloaded media in webkit's cache
     4        https://bugs.webkit.org/show_bug.cgi?id=119477
     5
     6        Reviewed by Xabier Rodriguez-Calvar.
     7
     8        Files cached on disk by MediaPlayerPrivateGStreamer are deleted only when the player is closed. If the
     9        WebProcess crashed, they're just left there in the cache directory. This patch changes the location
     10        of those temporary files to a proper temporary directory (/var/tmp, as those files aren't actually
     11        reusable, so they don't belong to a cache directory, and /tmp is a bad place because it's RAM-based on
     12        some distros), unlinks (deletes) them right after creation and also deletes any other stalled temporary
     13        file on the old legacy cache directory.
     14
     15        There's no API in GstPlaybin to control the temporary file location, so we do it manually by locating
     16        the GstDownloadBuffer element in the pipeline as soon as it's created, reconfiguring it with the right
     17        temporary file path and deleting the file as soon as it's created.
     18
     19        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
     20        (WebCore::MediaPlayerPrivateGStreamer::~MediaPlayerPrivateGStreamer): Stop listening to element-added.
     21        (WebCore::MediaPlayerPrivateGStreamer::uriDecodeBinElementAddedCallback): Look for GstDownloadBuffer.
     22        (WebCore::MediaPlayerPrivateGStreamer::downloadBufferFileCreatedCallback): Remove the file after creation.
     23        (WebCore::MediaPlayerPrivateGStreamer::purgeOldDownloadFiles): Delete legacy files.
     24        (WebCore::MediaPlayerPrivateGStreamer::sourceChanged): Listen to element-added signals on GstUriDecodeBin.
     25        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h: New reference to GstDownloadBuffer.
     26
    1272017-02-03  Antti Koivisto  <antti@apple.com>
    228
  • trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp

    r211562 r211627  
    2929#if ENABLE(VIDEO) && USE(GSTREAMER)
    3030
     31#include "FileSystem.h"
    3132#include "GStreamerUtilities.h"
    3233#include "URL.h"
     
    3839#include "TimeRanges.h"
    3940#include "WebKitWebSourceGStreamer.h"
     41#include <glib.h>
    4042#include <gst/gst.h>
    4143#include <gst/pbutils/missing-plugins.h>
     
    199201    }
    200202
     203    if (WEBKIT_IS_WEB_SRC(m_source.get()))
     204        g_signal_handlers_disconnect_by_func(GST_ELEMENT_PARENT(m_source.get()), reinterpret_cast<gpointer>(uriDecodeBinElementAddedCallback), this);
     205
    201206    if (m_autoAudioSink)
    202207        g_signal_handlers_disconnect_by_func(G_OBJECT(m_autoAudioSink.get()),
     
    13491354}
    13501355
     1356void MediaPlayerPrivateGStreamer::uriDecodeBinElementAddedCallback(GstBin* bin, GstElement* element, MediaPlayerPrivateGStreamer* player)
     1357{
     1358    if (g_strcmp0(G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(G_OBJECT(element))), "GstDownloadBuffer"))
     1359        return;
     1360
     1361    player->m_downloadBuffer = element;
     1362    g_signal_handlers_disconnect_by_func(bin, reinterpret_cast<gpointer>(uriDecodeBinElementAddedCallback), player);
     1363    g_signal_connect_swapped(element, "notify::temp-location", G_CALLBACK(downloadBufferFileCreatedCallback), player);
     1364
     1365    GUniqueOutPtr<char> oldDownloadTemplate;
     1366    g_object_get(element, "temp-template", &oldDownloadTemplate.outPtr(), nullptr);
     1367
     1368    GUniquePtr<char> newDownloadTemplate(g_build_filename(G_DIR_SEPARATOR_S, "var", "tmp", "WebKit-Media-XXXXXX", nullptr));
     1369    g_object_set(element, "temp-template", newDownloadTemplate.get(), nullptr);
     1370    GST_TRACE("Reconfigured file download template from '%s' to '%s'", oldDownloadTemplate.get(), newDownloadTemplate.get());
     1371
     1372    player->purgeOldDownloadFiles(oldDownloadTemplate.get());
     1373}
     1374
     1375void MediaPlayerPrivateGStreamer::downloadBufferFileCreatedCallback(MediaPlayerPrivateGStreamer* player)
     1376{
     1377    ASSERT(player->m_downloadBuffer);
     1378
     1379    g_signal_handlers_disconnect_by_func(player->m_downloadBuffer.get(), reinterpret_cast<gpointer>(downloadBufferFileCreatedCallback), player);
     1380
     1381    GUniqueOutPtr<char> downloadFile;
     1382    g_object_get(player->m_downloadBuffer.get(), "temp-location", &downloadFile.outPtr(), nullptr);
     1383    player->m_downloadBuffer = nullptr;
     1384
     1385    if (UNLIKELY(!deleteFile(downloadFile.get()))) {
     1386        GST_WARNING("Couldn't unlink media temporary file %s after creation", downloadFile.get());
     1387        return;
     1388    }
     1389
     1390    GST_TRACE("Unlinked media temporary file %s after creation", downloadFile.get());
     1391}
     1392
     1393void MediaPlayerPrivateGStreamer::purgeOldDownloadFiles(const char* downloadFileTemplate)
     1394{
     1395    if (!downloadFileTemplate)
     1396        return;
     1397
     1398    GUniquePtr<char> templatePath(g_path_get_dirname(downloadFileTemplate));
     1399    GUniquePtr<char> templateFile(g_path_get_basename(downloadFileTemplate));
     1400    String templatePattern = String(templateFile.get()).replace("X", "?");
     1401
     1402    for (auto& filePath : listDirectory(templatePath.get(), templatePattern)) {
     1403        if (UNLIKELY(!deleteFile(filePath))) {
     1404            GST_WARNING("Couldn't unlink legacy media temporary file: %s", filePath.utf8().data());
     1405            continue;
     1406        }
     1407
     1408        GST_TRACE("Unlinked legacy media temporary file: %s", filePath.utf8().data());
     1409    }
     1410}
     1411
    13511412void MediaPlayerPrivateGStreamer::sourceChanged()
    13521413{
     1414    if (WEBKIT_IS_WEB_SRC(m_source.get()))
     1415        g_signal_handlers_disconnect_by_func(GST_ELEMENT_PARENT(m_source.get()), reinterpret_cast<gpointer>(uriDecodeBinElementAddedCallback), this);
     1416
    13531417    m_source.clear();
    13541418    g_object_get(m_pipeline.get(), "source", &m_source.outPtr(), nullptr);
    13551419
    1356     if (WEBKIT_IS_WEB_SRC(m_source.get()))
     1420    if (WEBKIT_IS_WEB_SRC(m_source.get())) {
    13571421        webKitWebSrcSetMediaPlayer(WEBKIT_WEB_SRC(m_source.get()), m_player);
     1422        g_signal_connect(GST_ELEMENT_PARENT(m_source.get()), "element-added", G_CALLBACK(uriDecodeBinElementAddedCallback), this);
     1423    }
    13581424}
    13591425
  • trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h

    r209797 r211627  
    169169    bool canSaveMediaData() const override;
    170170
     171    void purgeOldDownloadFiles(const char*);
     172    static void uriDecodeBinElementAddedCallback(GstBin*, GstElement*, MediaPlayerPrivateGStreamer*);
     173    static void downloadBufferFileCreatedCallback(MediaPlayerPrivateGStreamer*);
     174
    171175protected:
    172176    void cacheDuration();
     
    243247#endif
    244248    GRefPtr<GstElement> m_autoAudioSink;
     249    GRefPtr<GstElement> m_downloadBuffer;
    245250    RefPtr<MediaPlayerRequestInstallMissingPluginsCallback> m_missingPluginsCallback;
    246251#if ENABLE(VIDEO_TRACK)
Note: See TracChangeset for help on using the changeset viewer.