Title: [169209] trunk/Source/WebCore
Revision
169209
Author
[email protected]
Date
2014-05-22 11:25:46 -0700 (Thu, 22 May 2014)

Log Message

[MSE] Stored samples are not freed when SourceBuffer is removed from MediaSource
https://bugs.webkit.org/show_bug.cgi?id=133174

Reviewed by Eric Carlson.

Clear out stored MediaSamples from SourceBuffer's TrackBuffer storage when
aborting loading. Also, report the memory cost of those samples, so that the
SourceBuffer will be GCd more readily.

Add a mechanism for reporting the size of a MediaSample:
* Modules/mediasource/SourceBuffer.h:
* platform/MediaSample.h:
* platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm:
* platform/mock/mediasource/MockSourceBufferPrivate.cpp:

Track the memory usage of a SampleMap when adding and removing samples, as well
as allowing the SampleMap to be cleared wholesale:
* Modules/mediasource/SampleMap.cpp:
(WebCore::SampleMap::clear): Release all stored MediaSamples.
(WebCore::SampleMap::addSample): Update m_totalSize.
(WebCore::SampleMap::removeSample): Ditto.
* Modules/mediasource/SampleMap.h:
(WebCore::SampleMap::SampleMap): Initialize m_totalSize.
(WebCore::SampleMap::sizeInBytes): Simple accessor.

Clear the stored samples when loading is aborted, and report the extra memory
cost
* Modules/mediasource/SourceBuffer.cpp:
(WebCore::SourceBuffer::SourceBuffer): Initialize m_reportedExtraMemoryCost.
(WebCore::SourceBuffer::removedFromMediaSource): Clear all stored samples.
(WebCore::SourceBuffer::sourceBufferPrivateAppendComplete): Call reportExtraMemoryCost().
(WebCore::SourceBuffer::reportExtraMemoryCost): Inform the vm of the new
    extra memory cost incurred by the object.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (169208 => 169209)


--- trunk/Source/WebCore/ChangeLog	2014-05-22 18:23:21 UTC (rev 169208)
+++ trunk/Source/WebCore/ChangeLog	2014-05-22 18:25:46 UTC (rev 169209)
@@ -1,3 +1,39 @@
+2014-05-22  Jer Noble  <[email protected]>
+
+        [MSE] Stored samples are not freed when SourceBuffer is removed from MediaSource
+        https://bugs.webkit.org/show_bug.cgi?id=133174
+
+        Reviewed by Eric Carlson.
+
+        Clear out stored MediaSamples from SourceBuffer's TrackBuffer storage when
+        aborting loading. Also, report the memory cost of those samples, so that the
+        SourceBuffer will be GCd more readily.
+
+        Add a mechanism for reporting the size of a MediaSample:
+        * Modules/mediasource/SourceBuffer.h:
+        * platform/MediaSample.h:
+        * platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm:
+        * platform/mock/mediasource/MockSourceBufferPrivate.cpp:
+
+        Track the memory usage of a SampleMap when adding and removing samples, as well
+        as allowing the SampleMap to be cleared wholesale:
+        * Modules/mediasource/SampleMap.cpp:
+        (WebCore::SampleMap::clear): Release all stored MediaSamples.
+        (WebCore::SampleMap::addSample): Update m_totalSize.
+        (WebCore::SampleMap::removeSample): Ditto.
+        * Modules/mediasource/SampleMap.h:
+        (WebCore::SampleMap::SampleMap): Initialize m_totalSize.
+        (WebCore::SampleMap::sizeInBytes): Simple accessor.
+
+        Clear the stored samples when loading is aborted, and report the extra memory
+        cost
+        * Modules/mediasource/SourceBuffer.cpp:
+        (WebCore::SourceBuffer::SourceBuffer): Initialize m_reportedExtraMemoryCost.
+        (WebCore::SourceBuffer::removedFromMediaSource): Clear all stored samples.
+        (WebCore::SourceBuffer::sourceBufferPrivateAppendComplete): Call reportExtraMemoryCost().
+        (WebCore::SourceBuffer::reportExtraMemoryCost): Inform the vm of the new
+            extra memory cost incurred by the object.
+
 2014-05-22  Enrica Casucci  <[email protected]>
 
         REGRESSION (WebKit2): Keyboard should have Search button in duckduckgo.com.

Modified: trunk/Source/WebCore/Modules/mediasource/SampleMap.cpp (169208 => 169209)


--- trunk/Source/WebCore/Modules/mediasource/SampleMap.cpp	2014-05-22 18:23:21 UTC (rev 169208)
+++ trunk/Source/WebCore/Modules/mediasource/SampleMap.cpp	2014-05-22 18:25:46 UTC (rev 169209)
@@ -80,12 +80,21 @@
     }
 };
 
+void SampleMap::clear()
+{
+    m_presentationSamples.clear();
+    m_decodeSamples.clear();
+    m_totalSize = 0;
+}
+
 void SampleMap::addSample(PassRefPtr<MediaSample> prpSample)
 {
     RefPtr<MediaSample> sample = prpSample;
     ASSERT(sample);
     m_presentationSamples.insert(MapType::value_type(sample->presentationTime(), sample));
     m_decodeSamples.insert(MapType::value_type(sample->decodeTime(), sample));
+
+    m_totalSize += sample->sizeInBytes();
 }
 
 void SampleMap::removeSample(MediaSample* sample)
@@ -93,6 +102,8 @@
     ASSERT(sample);
     m_presentationSamples.erase(sample->presentationTime());
     m_decodeSamples.erase(sample->decodeTime());
+
+    m_totalSize -= sample->sizeInBytes();
 }
 
 SampleMap::iterator SampleMap::findSampleContainingPresentationTime(const MediaTime& time)

Modified: trunk/Source/WebCore/Modules/mediasource/SampleMap.h (169208 => 169209)


--- trunk/Source/WebCore/Modules/mediasource/SampleMap.h	2014-05-22 18:23:21 UTC (rev 169208)
+++ trunk/Source/WebCore/Modules/mediasource/SampleMap.h	2014-05-22 18:25:46 UTC (rev 169209)
@@ -44,8 +44,15 @@
     typedef std::pair<iterator, iterator> iterator_range;
     typedef std::pair<reverse_iterator, reverse_iterator> reverse_iterator_range;
 
+    SampleMap()
+        : m_totalSize(0)
+    {
+    }
+
+    void clear();
     void addSample(PassRefPtr<MediaSample>);
     void removeSample(MediaSample*);
+    size_t sizeInBytes() const { return m_totalSize; }
 
     iterator presentationBegin() { return m_presentationSamples.begin(); }
     iterator presentationEnd() { return m_presentationSamples.end(); }
@@ -73,6 +80,7 @@
 private:
     MapType m_presentationSamples;
     MapType m_decodeSamples;
+    size_t m_totalSize;
 };
 
 }

Modified: trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp (169208 => 169209)


--- trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp	2014-05-22 18:23:21 UTC (rev 169208)
+++ trunk/Source/WebCore/Modules/mediasource/SourceBuffer.cpp	2014-05-22 18:25:46 UTC (rev 169209)
@@ -49,6 +49,9 @@
 #include "TimeRanges.h"
 #include "VideoTrackList.h"
 #include <map>
+#include <runtime/JSCInlines.h>
+#include <runtime/JSLock.h>
+#include <runtime/VM.h>
 #include <wtf/CurrentTime.h>
 #include <wtf/NeverDestroyed.h>
 
@@ -103,6 +106,7 @@
     , m_timeOfBufferingMonitor(monotonicallyIncreasingTime())
     , m_bufferedSinceLastMonitor(0)
     , m_averageBufferRate(0)
+    , m_reportedExtraMemoryCost(0)
     , m_pendingRemoveStart(MediaTime::invalidTime())
     , m_pendingRemoveEnd(MediaTime::invalidTime())
     , m_removeTimer(this, &SourceBuffer::removeTimerFired)
@@ -289,6 +293,11 @@
 
     abortIfUpdating();
 
+    for (auto& trackBufferPair : m_trackBufferMap.values()) {
+        trackBufferPair.samples.clear();
+        trackBufferPair.decodeQueue.clear();
+    }
+
     m_private->removedFromMediaSource();
     m_source = 0;
     m_asyncEventQueue.close();
@@ -446,6 +455,8 @@
 
     // 6. Asynchronously run the buffer append algorithm.
     m_appendBufferTimer.startOneShot(0);
+
+    reportExtraMemoryCost();
 }
 
 void SourceBuffer::appendBufferTimerFired(Timer<SourceBuffer>&)
@@ -516,6 +527,8 @@
         m_source->monitorSourceBuffers();
     for (auto iter = m_trackBufferMap.begin(), end = m_trackBufferMap.end(); iter != end; ++iter)
         provideMediaData(iter->value, iter->key);
+
+    reportExtraMemoryCost();
 }
 
 void SourceBuffer::removeCodedFrames(const MediaTime& start, const MediaTime& end)
@@ -1424,6 +1437,23 @@
     return unbufferedTime / m_averageBufferRate < timeRemaining;
 }
 
+void SourceBuffer::reportExtraMemoryCost()
+{
+    size_t extraMemoryCost = m_pendingAppendData.capacity();
+    for (auto& trackBuffer : m_trackBufferMap.values())
+        extraMemoryCost += trackBuffer.samples.sizeInBytes();
+
+    if (extraMemoryCost < m_reportedExtraMemoryCost)
+        return;
+
+    size_t extraMemoryCostDelta = extraMemoryCost - m_reportedExtraMemoryCost;
+    m_reportedExtraMemoryCost = extraMemoryCost;
+
+    JSC::JSLockHolder lock(scriptExecutionContext()->vm());
+    if (extraMemoryCostDelta > 0)
+        scriptExecutionContext()->vm().heap.reportExtraMemoryCost(extraMemoryCostDelta);
+}
+
 } // namespace WebCore
 
 #endif

Modified: trunk/Source/WebCore/Modules/mediasource/SourceBuffer.h (169208 => 169209)


--- trunk/Source/WebCore/Modules/mediasource/SourceBuffer.h	2014-05-22 18:23:21 UTC (rev 169208)
+++ trunk/Source/WebCore/Modules/mediasource/SourceBuffer.h	2014-05-22 18:25:46 UTC (rev 169209)
@@ -156,6 +156,8 @@
     void removeTimerFired(Timer<SourceBuffer>*);
     void removeCodedFrames(const MediaTime& start, const MediaTime& end);
 
+    void reportExtraMemoryCost();
+
     Ref<SourceBufferPrivate> m_private;
     MediaSource* m_source;
     GenericEventQueue m_asyncEventQueue;
@@ -188,6 +190,8 @@
     double m_bufferedSinceLastMonitor;
     double m_averageBufferRate;
 
+    size_t m_reportedExtraMemoryCost;
+
     MediaTime m_pendingRemoveStart;
     MediaTime m_pendingRemoveEnd;
     Timer<SourceBuffer> m_removeTimer;

Modified: trunk/Source/WebCore/platform/MediaSample.h (169208 => 169209)


--- trunk/Source/WebCore/platform/MediaSample.h	2014-05-22 18:23:21 UTC (rev 169208)
+++ trunk/Source/WebCore/platform/MediaSample.h	2014-05-22 18:25:46 UTC (rev 169209)
@@ -55,6 +55,7 @@
     virtual MediaTime decodeTime() const = 0;
     virtual MediaTime duration() const = 0;
     virtual AtomicString trackID() const = 0;
+    virtual size_t sizeInBytes() const = 0;
 
     enum SampleFlags {
         None = 0,

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm (169208 => 169209)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm	2014-05-22 18:23:21 UTC (rev 169208)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm	2014-05-22 18:25:46 UTC (rev 169209)
@@ -89,6 +89,7 @@
 SOFT_LINK(CoreMedia, CMSampleBufferGetFormatDescription, CMFormatDescriptionRef, (CMSampleBufferRef sbuf), (sbuf))
 SOFT_LINK(CoreMedia, CMSampleBufferGetPresentationTimeStamp, CMTime, (CMSampleBufferRef sbuf), (sbuf))
 SOFT_LINK(CoreMedia, CMSampleBufferGetSampleAttachmentsArray, CFArrayRef, (CMSampleBufferRef sbuf, Boolean createIfNecessary), (sbuf, createIfNecessary))
+SOFT_LINK(CoreMedia, CMSampleBufferGetTotalSampleSize, size_t, (CMSampleBufferRef sbuf), (sbuf))
 SOFT_LINK(CoreMedia, CMFormatDescriptionGetMediaSubType, FourCharCode, (CMFormatDescriptionRef desc), (desc))
 SOFT_LINK(CoreMedia, CMSetAttachment, void, (CMAttachmentBearerRef target, CFStringRef key, CFTypeRef value, CMAttachmentMode attachmentMode), (target, key, value, attachmentMode))
 SOFT_LINK(CoreMedia, CMVideoFormatDescriptionGetPresentationDimensions, CGSize, (CMVideoFormatDescriptionRef videoDesc, Boolean usePixelAspectRatio, Boolean useCleanAperture), (videoDesc, usePixelAspectRatio, useCleanAperture))
@@ -292,6 +293,7 @@
     virtual MediaTime decodeTime() const override { return toMediaTime(CMSampleBufferGetDecodeTimeStamp(m_sample.get())); }
     virtual MediaTime duration() const override { return toMediaTime(CMSampleBufferGetDuration(m_sample.get())); }
     virtual AtomicString trackID() const override { return m_id; }
+    virtual size_t sizeInBytes() const override { return CMSampleBufferGetTotalSampleSize(m_sample.get()); }
 
     virtual SampleFlags flags() const override;
     virtual PlatformSample platformSample() override;

Modified: trunk/Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.cpp (169208 => 169209)


--- trunk/Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.cpp	2014-05-22 18:23:21 UTC (rev 169208)
+++ trunk/Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.cpp	2014-05-22 18:25:46 UTC (rev 169209)
@@ -50,6 +50,7 @@
     virtual MediaTime decodeTime() const override { return m_box.decodeTimestamp(); }
     virtual MediaTime duration() const override { return m_box.duration(); }
     virtual AtomicString trackID() const override { return m_id; }
+    virtual size_t sizeInBytes() const override { return sizeof(m_box); }
 
     virtual SampleFlags flags() const override;
     virtual PlatformSample platformSample() override;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to