Title: [186054] trunk/Source/WebCore
Revision
186054
Author
[email protected]
Date
2015-06-28 15:16:04 -0700 (Sun, 28 Jun 2015)

Log Message

[iOS] Drop buffered data in paused media elements on memory pressure.
<https://webkit.org/b/146369>
<rdar://problem/20366883>

Reviewed by Eric Carlson.

To avoid getting crushed under mediaserverd memory growth when viewing
a page with multiple media elements, add a step to the memory pressure
handler that drops buffered data from all media elements that are
not currently playing.

On a test page with a bunch of embedded YouTube videos, this pass frees
up ~4MB per paused video when the system memory pressure hits.

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::allMediaElements):
(WebCore::HTMLMediaElement::HTMLMediaElement):
(WebCore::HTMLMediaElement::~HTMLMediaElement):
(WebCore::HTMLMediaElement::purgeBufferedDataIfPossible):
* html/HTMLMediaElement.h:
* platform/MemoryPressureHandler.cpp:
(WebCore::MemoryPressureHandler::releaseCriticalMemory):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (186053 => 186054)


--- trunk/Source/WebCore/ChangeLog	2015-06-28 20:36:40 UTC (rev 186053)
+++ trunk/Source/WebCore/ChangeLog	2015-06-28 22:16:04 UTC (rev 186054)
@@ -1,3 +1,28 @@
+2015-06-28  Andreas Kling  <[email protected]>
+
+        [iOS] Drop buffered data in paused media elements on memory pressure.
+        <https://webkit.org/b/146369>
+        <rdar://problem/20366883>
+
+        Reviewed by Eric Carlson.
+
+        To avoid getting crushed under mediaserverd memory growth when viewing
+        a page with multiple media elements, add a step to the memory pressure
+        handler that drops buffered data from all media elements that are
+        not currently playing.
+
+        On a test page with a bunch of embedded YouTube videos, this pass frees
+        up ~4MB per paused video when the system memory pressure hits.
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::allMediaElements):
+        (WebCore::HTMLMediaElement::HTMLMediaElement):
+        (WebCore::HTMLMediaElement::~HTMLMediaElement):
+        (WebCore::HTMLMediaElement::purgeBufferedDataIfPossible):
+        * html/HTMLMediaElement.h:
+        * platform/MemoryPressureHandler.cpp:
+        (WebCore::MemoryPressureHandler::releaseCriticalMemory):
+
 2015-06-28  Chris Dumez  <[email protected]>
 
         Crash: com.apple.WebKit.WebContent at com.apple.WebCore: WebCore::CachedFrameBase::restore + 333

Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (186053 => 186054)


--- trunk/Source/WebCore/html/HTMLMediaElement.cpp	2015-06-28 20:36:40 UTC (rev 186053)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp	2015-06-28 22:16:04 UTC (rev 186054)
@@ -276,6 +276,12 @@
     bool hasSrcLang;
 };
 
+HashSet<HTMLMediaElement*>& HTMLMediaElement::allMediaElements()
+{
+    static NeverDestroyed<HashSet<HTMLMediaElement*>> elements;
+    return elements;
+}
+
 HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& document, bool createdByParser)
     : HTMLElement(tagName, document)
     , ActiveDOMObject(&document)
@@ -362,6 +368,8 @@
     , m_mediaStreamSrcObject(nullptr)
 #endif
 {
+    allMediaElements().add(this);
+
     LOG(Media, "HTMLMediaElement::HTMLMediaElement(%p)", this);
     setHasCustomStyleResolveCallbacks();
 
@@ -408,6 +416,8 @@
 {
     LOG(Media, "HTMLMediaElement::~HTMLMediaElement(%p)", this);
 
+    allMediaElements().remove(this);
+
     m_asyncEventQueue.close();
 
     setShouldDelayLoadEvent(false);
@@ -6395,6 +6405,17 @@
         m_player->setShouldBufferData(shouldBuffer);
 }
 
+void HTMLMediaElement::purgeBufferedDataIfPossible()
+{
+#if PLATFORM(IOS)
+    // This is called to relieve memory pressure. Turning off buffering causes the media playback
+    // daemon to release memory associated with queued-up video frames.
+    // We turn it back on right away, but new frames won't get loaded unless playback is resumed.
+    setShouldBufferData(false);
+    setShouldBufferData(true);
+#endif
+}
+
 bool HTMLMediaElement::canSaveMediaData() const
 {
     if (m_player)

Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (186053 => 186054)


--- trunk/Source/WebCore/html/HTMLMediaElement.h	2015-06-28 20:36:40 UTC (rev 186053)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h	2015-06-28 22:16:04 UTC (rev 186054)
@@ -117,6 +117,8 @@
     virtual bool hasVideo() const override { return false; }
     virtual bool hasAudio() const override;
 
+    static HashSet<HTMLMediaElement*>& allMediaElements();
+
     void rewind(double timeDelta);
     WEBCORE_EXPORT virtual void returnToRealtime() override;
 
@@ -208,6 +210,8 @@
     double minFastReverseRate() const;
     double maxFastForwardRate() const;
 
+    void purgeBufferedDataIfPossible();
+
 // captions
     bool webkitHasClosedCaptions() const;
     bool webkitClosedCaptionsVisible() const;

Modified: trunk/Source/WebCore/platform/MemoryPressureHandler.cpp (186053 => 186054)


--- trunk/Source/WebCore/platform/MemoryPressureHandler.cpp	2015-06-28 20:36:40 UTC (rev 186053)
+++ trunk/Source/WebCore/platform/MemoryPressureHandler.cpp	2015-06-28 22:16:04 UTC (rev 186054)
@@ -31,6 +31,7 @@
 #include "FontCache.h"
 #include "FontCascade.h"
 #include "GCController.h"
+#include "HTMLMediaElement.h"
 #include "JSDOMWindow.h"
 #include "MemoryCache.h"
 #include "Page.h"
@@ -142,6 +143,14 @@
         FontCache::singleton().invalidate();
     }
 
+    {
+        ReliefLogger log("Dropping buffered data from paused media elements");
+        for (auto* mediaElement: HTMLMediaElement::allMediaElements()) {
+            if (mediaElement->paused())
+                mediaElement->purgeBufferedDataIfPossible();
+        }
+    }
+
     if (synchronous == Synchronous::Yes) {
         ReliefLogger log("Collecting _javascript_ garbage");
         GCController::singleton().garbageCollectNow();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to