Title: [264762] trunk
Revision
264762
Author
calva...@igalia.com
Date
2020-07-23 07:55:19 -0700 (Thu, 23 Jul 2020)

Log Message

[GStreamer] gst_buffer_unmap: assertion 'GST_IS_BUFFER (buffer)' failed
https://bugs.webkit.org/show_bug.cgi?id=213364

Reviewed by Philippe Normand.

Source/WebCore:

In some cases as in passing init datas around, the InitData that
contains a SharedBuffer that contains a non-reffed mapped buffer
can outlive the buffer itself, creating this problem.

In this patch we make a new class called GstMappedOwnedBuffer that
is to map read-only buffers and that is used for the InitData
SharedBuffer. GstMappedBuffer does not support SharedBuffer
anymore and is not ref counted anymore as it is intended for short
term and quick usage.

Test: imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-setmediakeys-to-multiple-video-elements.https.html

* platform/SharedBuffer.cpp:
(WebCore::SharedBuffer::create):
(WebCore::SharedBuffer::SharedBuffer):
(WebCore::SharedBuffer::DataSegment::data const):
(WebCore::SharedBuffer::DataSegment::size const):
* platform/SharedBuffer.h:
* platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp:
(webKitWebAudioSrcAllocateBuffersAndRenderAudio):
* platform/graphics/gstreamer/GStreamerCommon.cpp:
(WebCore::GstMappedBuffer::createVector const):
(WebCore::GstMappedOwnedBuffer::createSharedBuffer):
* platform/graphics/gstreamer/GStreamerCommon.h:
(WebCore::GstMappedBuffer::GstMappedBuffer):
(WebCore::GstMappedBuffer::~GstMappedBuffer):
(WebCore::GstMappedBuffer::isValid const):
(WebCore::GstMappedBuffer::data):
(WebCore::GstMappedBuffer::data const):
(WebCore::GstMappedBuffer::size const):
(WebCore::GstMappedBuffer::operator bool const):
(WebCore::GstMappedBuffer::operator! const):
(WebCore::GstMappedOwnedBuffer::create):
(WebCore::GstMappedOwnedBuffer::GstMappedOwnedBuffer):
(WebCore::operator==):
* platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp:
(WebCore::InbandTextTrackPrivateGStreamer::notifyTrackOfSample):
* platform/graphics/gstreamer/eme/CDMProxyThunder.cpp:
(WebCore::CDMProxyThunder::getDecryptionSession const):
* platform/graphics/gstreamer/eme/GStreamerEMEUtilities.h:
(WebCore::InitData::InitData):
* platform/graphics/gstreamer/eme/WebKitClearKeyDecryptorGStreamer.cpp:
(decrypt):
* platform/mediastream/gstreamer/MockRealtimeAudioSourceGStreamer.cpp:
(WebCore::MockRealtimeAudioSourceGStreamer::render):
* platform/mediastream/gstreamer/RealtimeOutgoingAudioSourceLibWebRTC.cpp:
(WebCore::RealtimeOutgoingAudioSourceLibWebRTC::pullAudioData):
* platform/mediastream/gstreamer/RealtimeOutgoingVideoSourceLibWebRTC.cpp:
(WebCore::RealtimeOutgoingVideoSourceLibWebRTC::createBlackFrame):
* platform/mediastream/libwebrtc/GStreamerVideoEncoderFactory.cpp:
(WebCore::GStreamerVideoEncoder::Fragmentize):

Tools:

Reworked tests for GstMappedBuffer and added tests for
GstMappedOwnedBuffer.

* TestWebKitAPI/Tests/WebCore/gstreamer/GstMappedBuffer.cpp:
(TestWebKitAPI::TEST_F):

LayoutTests:

* platform/glib/TestExpectations: flagged
imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-setmediakeys-to-multiple-video-elements.https.html
as Pass.

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (264761 => 264762)


--- trunk/LayoutTests/ChangeLog	2020-07-23 14:33:26 UTC (rev 264761)
+++ trunk/LayoutTests/ChangeLog	2020-07-23 14:55:19 UTC (rev 264762)
@@ -1,3 +1,14 @@
+2020-07-23  Xabier Rodriguez Calvar  <calva...@igalia.com>
+
+        [GStreamer] gst_buffer_unmap: assertion 'GST_IS_BUFFER (buffer)' failed
+        https://bugs.webkit.org/show_bug.cgi?id=213364
+
+        Reviewed by Philippe Normand.
+
+        * platform/glib/TestExpectations: flagged
+        imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-setmediakeys-to-multiple-video-elements.https.html
+        as Pass.
+
 2020-07-23  Karl Rackler  <rack...@apple.com>
 
         [ iOS wk2 debug ] imported/w3c/web-platform-tests/html/semantics/scripting-1/the-script-element/moving-between-documents/before-prepare-createHTMLDocument-fetch-error-external-classic.html is a flaky failure

Modified: trunk/LayoutTests/platform/glib/TestExpectations (264761 => 264762)


--- trunk/LayoutTests/platform/glib/TestExpectations	2020-07-23 14:33:26 UTC (rev 264761)
+++ trunk/LayoutTests/platform/glib/TestExpectations	2020-07-23 14:55:19 UTC (rev 264762)
@@ -709,7 +709,6 @@
 webkit.org/b/210965 imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-multikey-sequential-readyState.https.html [ Failure ]
 webkit.org/b/210966 imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-setmediakeys-again-after-playback.https.html [ Crash Pass ]
 webkit.org/b/178707 imported/w3c/web-platform-tests/encrypted-media/encrypted-media-default-feature-policy.https.sub.html [ Skip ]
-webkit.org/b/213364 imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-setmediakeys-to-multiple-video-elements.https.html [ Crash Pass ]
 
 imported/w3c/web-platform-tests/encrypted-media/clearkey-check-encryption-scheme.https.html [ Pass ]
 imported/w3c/web-platform-tests/encrypted-media/clearkey-check-initdata-type.https.html [ Pass ]
@@ -736,6 +735,7 @@
 imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-setmediakeys.https.html [ Pass ]
 imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-setmediakeys-multiple-times-with-different-mediakeys.https.html [ Pass ]
 imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-setmediakeys-multiple-times-with-the-same-mediakeys.https.html [ Pass ]
+imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-setmediakeys-to-multiple-video-elements.https.html [ Pass ]
 imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-syntax-mediakeysession.https.html [ Pass ]
 imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-syntax-mediakeys.https.html [ Pass ]
 imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-syntax-mediakeysystemaccess.https.html [ Pass ]

Modified: trunk/Source/WebCore/ChangeLog (264761 => 264762)


--- trunk/Source/WebCore/ChangeLog	2020-07-23 14:33:26 UTC (rev 264761)
+++ trunk/Source/WebCore/ChangeLog	2020-07-23 14:55:19 UTC (rev 264762)
@@ -1,3 +1,62 @@
+2020-07-23  Xabier Rodriguez Calvar  <calva...@igalia.com>
+
+        [GStreamer] gst_buffer_unmap: assertion 'GST_IS_BUFFER (buffer)' failed
+        https://bugs.webkit.org/show_bug.cgi?id=213364
+
+        Reviewed by Philippe Normand.
+
+        In some cases as in passing init datas around, the InitData that
+        contains a SharedBuffer that contains a non-reffed mapped buffer
+        can outlive the buffer itself, creating this problem.
+
+        In this patch we make a new class called GstMappedOwnedBuffer that
+        is to map read-only buffers and that is used for the InitData
+        SharedBuffer. GstMappedBuffer does not support SharedBuffer
+        anymore and is not ref counted anymore as it is intended for short
+        term and quick usage.
+
+        Test: imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-setmediakeys-to-multiple-video-elements.https.html
+
+        * platform/SharedBuffer.cpp:
+        (WebCore::SharedBuffer::create):
+        (WebCore::SharedBuffer::SharedBuffer):
+        (WebCore::SharedBuffer::DataSegment::data const):
+        (WebCore::SharedBuffer::DataSegment::size const):
+        * platform/SharedBuffer.h:
+        * platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp:
+        (webKitWebAudioSrcAllocateBuffersAndRenderAudio):
+        * platform/graphics/gstreamer/GStreamerCommon.cpp:
+        (WebCore::GstMappedBuffer::createVector const):
+        (WebCore::GstMappedOwnedBuffer::createSharedBuffer):
+        * platform/graphics/gstreamer/GStreamerCommon.h:
+        (WebCore::GstMappedBuffer::GstMappedBuffer):
+        (WebCore::GstMappedBuffer::~GstMappedBuffer):
+        (WebCore::GstMappedBuffer::isValid const):
+        (WebCore::GstMappedBuffer::data):
+        (WebCore::GstMappedBuffer::data const):
+        (WebCore::GstMappedBuffer::size const):
+        (WebCore::GstMappedBuffer::operator bool const):
+        (WebCore::GstMappedBuffer::operator! const):
+        (WebCore::GstMappedOwnedBuffer::create):
+        (WebCore::GstMappedOwnedBuffer::GstMappedOwnedBuffer):
+        (WebCore::operator==):
+        * platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp:
+        (WebCore::InbandTextTrackPrivateGStreamer::notifyTrackOfSample):
+        * platform/graphics/gstreamer/eme/CDMProxyThunder.cpp:
+        (WebCore::CDMProxyThunder::getDecryptionSession const):
+        * platform/graphics/gstreamer/eme/GStreamerEMEUtilities.h:
+        (WebCore::InitData::InitData):
+        * platform/graphics/gstreamer/eme/WebKitClearKeyDecryptorGStreamer.cpp:
+        (decrypt):
+        * platform/mediastream/gstreamer/MockRealtimeAudioSourceGStreamer.cpp:
+        (WebCore::MockRealtimeAudioSourceGStreamer::render):
+        * platform/mediastream/gstreamer/RealtimeOutgoingAudioSourceLibWebRTC.cpp:
+        (WebCore::RealtimeOutgoingAudioSourceLibWebRTC::pullAudioData):
+        * platform/mediastream/gstreamer/RealtimeOutgoingVideoSourceLibWebRTC.cpp:
+        (WebCore::RealtimeOutgoingVideoSourceLibWebRTC::createBlackFrame):
+        * platform/mediastream/libwebrtc/GStreamerVideoEncoderFactory.cpp:
+        (WebCore::GStreamerVideoEncoder::Fragmentize):
+
 2020-07-23  Mark Lam  <mark....@apple.com>
 
         Fix missing exception checks below RTCPeerConnection.generateCertificate().

Modified: trunk/Source/WebCore/platform/SharedBuffer.cpp (264761 => 264762)


--- trunk/Source/WebCore/platform/SharedBuffer.cpp	2020-07-23 14:33:26 UTC (rev 264761)
+++ trunk/Source/WebCore/platform/SharedBuffer.cpp	2020-07-23 14:55:19 UTC (rev 264762)
@@ -58,13 +58,12 @@
 }
 
 #if USE(GSTREAMER)
-Ref<SharedBuffer> SharedBuffer::create(GstMappedBuffer& mappedBuffer)
+Ref<SharedBuffer> SharedBuffer::create(GstMappedOwnedBuffer& mappedBuffer)
 {
-    ASSERT(mappedBuffer.isSharable());
     return adoptRef(*new SharedBuffer(mappedBuffer));
 }
 
-SharedBuffer::SharedBuffer(GstMappedBuffer& mappedBuffer)
+SharedBuffer::SharedBuffer(GstMappedOwnedBuffer& mappedBuffer)
     : m_size(mappedBuffer.size())
 {
     m_segments.append({0, DataSegment::create(&mappedBuffer)});
@@ -244,7 +243,7 @@
         [](const GRefPtr<GBytes>& data) { return reinterpret_cast<const char*>(g_bytes_get_data(data.get(), nullptr)); },
 #endif
 #if USE(GSTREAMER)
-        [](const RefPtr<GstMappedBuffer>& data) { return reinterpret_cast<const char*>(data->data()); },
+        [](const RefPtr<GstMappedOwnedBuffer>& data) { return reinterpret_cast<const char*>(data->data()); },
 #endif
         [](const FileSystem::MappedFileData& data) { return reinterpret_cast<const char*>(data.data()); }
     );
@@ -325,7 +324,7 @@
         [](const GRefPtr<GBytes>& data) { return g_bytes_get_size(data.get()); },
 #endif
 #if USE(GSTREAMER)
-        [](const RefPtr<GstMappedBuffer>& data) { return data->size(); },
+        [](const RefPtr<GstMappedOwnedBuffer>& data) { return data->size(); },
 #endif
         [](const FileSystem::MappedFileData& data) { return data.size(); }
     );

Modified: trunk/Source/WebCore/platform/SharedBuffer.h (264761 => 264762)


--- trunk/Source/WebCore/platform/SharedBuffer.h	2020-07-23 14:33:26 UTC (rev 264761)
+++ trunk/Source/WebCore/platform/SharedBuffer.h	2020-07-23 14:55:19 UTC (rev 264762)
@@ -100,7 +100,7 @@
 #endif
 
 #if USE(GSTREAMER)
-    static Ref<SharedBuffer> create(GstMappedBuffer&);
+    static Ref<SharedBuffer> create(GstMappedOwnedBuffer&);
 #endif
     // Calling data() causes all the data segments to be copied into one segment if they are not already.
     // Iterate the segments using begin() and end() instead.
@@ -147,7 +147,7 @@
         static Ref<DataSegment> create(GRefPtr<GBytes>&& data) { return adoptRef(*new DataSegment(WTFMove(data))); }
 #endif
 #if USE(GSTREAMER)
-        static Ref<DataSegment> create(RefPtr<GstMappedBuffer>&& data) { return adoptRef(*new DataSegment(WTFMove(data))); }
+        static Ref<DataSegment> create(RefPtr<GstMappedOwnedBuffer>&& data) { return adoptRef(*new DataSegment(WTFMove(data))); }
 #endif
         static Ref<DataSegment> create(FileSystem::MappedFileData&& data) { return adoptRef(*new DataSegment(WTFMove(data))); }
 
@@ -171,7 +171,7 @@
             : m_immutableData(WTFMove(data)) { }
 #endif
 #if USE(GSTREAMER)
-        DataSegment(RefPtr<GstMappedBuffer>&& data)
+        DataSegment(RefPtr<GstMappedOwnedBuffer>&& data)
             : m_immutableData(WTFMove(data)) { }
 #endif
         DataSegment(FileSystem::MappedFileData&& data)
@@ -188,7 +188,7 @@
             GRefPtr<GBytes>,
 #endif
 #if USE(GSTREAMER)
-            RefPtr<GstMappedBuffer>,
+            RefPtr<GstMappedOwnedBuffer>,
 #endif
             FileSystem::MappedFileData> m_immutableData;
         friend class SharedBuffer;
@@ -230,7 +230,7 @@
     explicit SharedBuffer(GBytes*);
 #endif
 #if USE(GSTREAMER)
-    explicit SharedBuffer(GstMappedBuffer&);
+    explicit SharedBuffer(GstMappedOwnedBuffer&);
 #endif
 
     void combineIntoOneSegment() const;

Modified: trunk/Source/WebCore/platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp (264761 => 264762)


--- trunk/Source/WebCore/platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp	2020-07-23 14:33:26 UTC (rev 264761)
+++ trunk/Source/WebCore/platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp	2020-07-23 14:55:19 UTC (rev 264762)
@@ -327,7 +327,7 @@
 
     Vector<GRefPtr<GstBuffer>> channelBufferList;
     channelBufferList.reserveInitialCapacity(priv->sources.size());
-    Vector<RefPtr<GstMappedBuffer>> mappedBuffers;
+    Vector<GstMappedBuffer> mappedBuffers;
     mappedBuffers.reserveInitialCapacity(priv->sources.size());
     for (unsigned i = 0; i < priv->sources.size(); ++i) {
         GRefPtr<GstBuffer> buffer;
@@ -342,10 +342,10 @@
         ASSERT(buffer);
         GST_BUFFER_TIMESTAMP(buffer.get()) = timestamp;
         GST_BUFFER_DURATION(buffer.get()) = duration;
-        auto mappedBuffer = GstMappedBuffer::create(buffer.get(), GST_MAP_READWRITE);
+        GstMappedBuffer mappedBuffer(buffer.get(), GST_MAP_READWRITE);
         ASSERT(mappedBuffer);
         mappedBuffers.uncheckedAppend(WTFMove(mappedBuffer));
-        priv->bus->setChannelMemory(i, reinterpret_cast<float*>(mappedBuffers[i]->data()), priv->framesToPull);
+        priv->bus->setChannelMemory(i, reinterpret_cast<float*>(mappedBuffers[i].data()), priv->framesToPull);
         channelBufferList.uncheckedAppend(WTFMove(buffer));
     }
 

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.cpp (264761 => 264762)


--- trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.cpp	2020-07-23 14:33:26 UTC (rev 264761)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.cpp	2020-07-23 14:55:19 UTC (rev 264762)
@@ -26,7 +26,6 @@
 #include "GLVideoSinkGStreamer.h"
 #include "GstAllocatorFastMalloc.h"
 #include "IntSize.h"
-#include "SharedBuffer.h"
 #include <gst/audio/audio-info.h>
 #include <gst/gst.h>
 #include <mutex>
@@ -396,22 +395,18 @@
     g_signal_connect(bus.get(), "message", G_CALLBACK(simpleBusMessageCallback), pipeline);
 }
 
-Ref<SharedBuffer> GstMappedBuffer::createSharedBuffer()
+Vector<uint8_t> GstMappedBuffer::createVector() const
 {
-    // SharedBuffer provides a read-only view on what it expects are
-    // immutable data. Do not create one is writable and hence mutable.
-    RELEASE_ASSERT(isSharable());
-
-    return SharedBuffer::create(*this);
-}
-
-Vector<uint8_t> GstMappedBuffer::createVector()
-{
     Vector<uint8_t> vector;
     vector.append(data(), size());
     return vector;
 }
 
+Ref<SharedBuffer> GstMappedOwnedBuffer::createSharedBuffer()
+{
+    return SharedBuffer::create(*this);
+}
+
 bool isGStreamerPluginAvailable(const char* name)
 {
     GRefPtr<GstPlugin> plugin = adoptGRef(gst_registry_find_plugin(gst_registry_get(), name));

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h (264761 => 264762)


--- trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h	2020-07-23 14:33:26 UTC (rev 264761)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h	2020-07-23 14:55:19 UTC (rev 264762)
@@ -82,47 +82,53 @@
     return static_cast<GstClockTime>(toGstUnsigned64Time(mediaTime));
 }
 
-class GstMappedBuffer : public ThreadSafeRefCounted<GstMappedBuffer> {
+class GstMappedBuffer {
+    WTF_MAKE_NONCOPYABLE(GstMappedBuffer);
 public:
-    static RefPtr<GstMappedBuffer> create(const GRefPtr<GstBuffer>& buffer, GstMapFlags flags)
+
+    GstMappedBuffer(GstMappedBuffer&& other)
+        : m_buffer(other.m_buffer)
+        , m_info(other.m_info)
+        , m_isValid(other.m_isValid)
     {
-        return create(buffer.get(), flags);
+        other.m_isValid = false;
     }
 
-    static RefPtr<GstMappedBuffer> create(GstBuffer* buffer, GstMapFlags flags)
+    // This GstBuffer is [ transfer none ], meaning that no reference
+    // is increased. Hence, this buffer must outlive the mapped
+    // buffer.
+    GstMappedBuffer(GstBuffer* buffer, GstMapFlags flags)
+        : m_buffer(buffer)
     {
-        GstMapInfo info;
-        if (!gst_buffer_map(buffer, &info, flags))
-            return nullptr;
-        return adoptRef(new GstMappedBuffer(buffer, WTFMove(info)));
+        ASSERT(GST_IS_BUFFER(buffer));
+        m_isValid = gst_buffer_map(m_buffer, &m_info, flags);
     }
 
     // Unfortunately, GST_MAP_READWRITE is defined out of line from the MapFlags
     // enum as an int, and C++ is careful to not implicity convert it to an enum.
-    static RefPtr<GstMappedBuffer> create(GstBuffer* buffer, int flags)
-    {
-        return GstMappedBuffer::create(buffer, static_cast<GstMapFlags>(flags));
-    }
+    GstMappedBuffer(GstBuffer* buffer, int flags)
+        : GstMappedBuffer(buffer, static_cast<GstMapFlags>(flags)) { }
+    GstMappedBuffer(const GRefPtr<GstBuffer>& buffer, GstMapFlags flags)
+        : GstMappedBuffer(buffer.get(), flags) { }
 
-    ~GstMappedBuffer()
+    virtual ~GstMappedBuffer()
     {
-        gst_buffer_unmap(m_buffer, &m_info);
+        if (m_isValid) {
+            m_isValid = false;
+            gst_buffer_unmap(m_buffer, &m_info);
+        }
     }
 
-    uint8_t* data() { return static_cast<uint8_t*>(m_info.data); }
-    const uint8_t* data() const { return static_cast<uint8_t*>(m_info.data); }
-    size_t size() const { return static_cast<size_t>(m_info.size); }
-    bool isSharable() const { return !(m_info.flags & GST_MAP_WRITE); }
-    Ref<SharedBuffer> createSharedBuffer();
-    Vector<uint8_t> createVector();
+    bool isValid() const { return m_isValid; }
+    uint8_t* data() { RELEASE_ASSERT(m_isValid); return static_cast<uint8_t*>(m_info.data); }
+    const uint8_t* data() const { RELEASE_ASSERT(m_isValid); return static_cast<uint8_t*>(m_info.data); }
+    size_t size() const { ASSERT(m_isValid); return m_isValid ? static_cast<size_t>(m_info.size) : 0; }
+    Vector<uint8_t> createVector() const;
 
+    explicit operator bool() const { return m_isValid; }
+    bool operator!() const { return !m_isValid; }
+
 private:
-    GstMappedBuffer(GstBuffer* buffer, GstMapInfo&& info)
-        : m_buffer(buffer)
-        , m_info(WTFMove(info))
-    {
-    }
-
     friend bool operator==(const GstMappedBuffer&, const GstMappedBuffer&);
     friend bool operator==(const GstMappedBuffer&, const GstBuffer*);
     friend bool operator==(const GstBuffer* a, const GstMappedBuffer& b) { return operator==(b, a); }
@@ -129,17 +135,61 @@
 
     GstBuffer* m_buffer { nullptr };
     GstMapInfo m_info;
+    bool m_isValid { false };
 };
 
+// This class maps only buffers in GST_MAP_READ mode to be able to
+// bump the reference count and keep it alive during the life of this
+// object.
+class GstMappedOwnedBuffer : public GstMappedBuffer, public ThreadSafeRefCounted<GstMappedOwnedBuffer> {
+
+public:
+    static RefPtr<GstMappedOwnedBuffer> create(GRefPtr<GstBuffer>&& buffer)
+    {
+        auto* mappedBuffer = new GstMappedOwnedBuffer(WTFMove(buffer));
+        if (!mappedBuffer->isValid()) {
+            delete mappedBuffer;
+            return nullptr;
+        }
+
+        return adoptRef(mappedBuffer);
+    }
+
+    static RefPtr<GstMappedOwnedBuffer> create(const GRefPtr<GstBuffer>& buffer)
+    {
+        return create(GRefPtr(buffer));
+    }
+
+    // This GstBuffer is [ transfer none ], meaning the reference
+    // count is increased during the life of this object.
+    static RefPtr<GstMappedOwnedBuffer> create(GstBuffer* buffer)
+    {
+        return create(GRefPtr(buffer));
+    }
+
+    Ref<SharedBuffer> createSharedBuffer();
+
+private:
+    GstMappedOwnedBuffer(GRefPtr<GstBuffer>&& buffer)
+        : GstMappedBuffer(buffer, GST_MAP_READ)
+        , m_ownedBuffer(WTFMove(buffer)) { }
+
+    GRefPtr<GstBuffer> m_ownedBuffer;
+};
+
 inline bool operator==(const GstMappedBuffer& a, const GstMappedBuffer& b)
 {
-    return a.size() == b.size() && !gst_buffer_memcmp(a.m_buffer, 0, b.data(), b.size());
+    ASSERT(a.isValid());
+    ASSERT(b.isValid());
+    return a.isValid() && b.isValid() && a.size() == b.size() && !gst_buffer_memcmp(a.m_buffer, 0, b.data(), b.size());
 }
 
 inline bool operator==(const GstMappedBuffer& a, const GstBuffer* b)
 {
+    ASSERT(a.isValid());
+    ASSERT(GST_IS_BUFFER(b));
     GstBuffer* nonConstB = const_cast<GstBuffer*>(b);
-    return a.size() == gst_buffer_get_size(nonConstB) && !gst_buffer_memcmp(nonConstB, 0, a.data(), a.size());
+    return a.isValid() && GST_IS_BUFFER(b) && a.size() == gst_buffer_get_size(nonConstB) && !gst_buffer_memcmp(nonConstB, 0, a.data(), a.size());
 }
 
 class GstMappedFrame {

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp (264761 => 264762)


--- trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp	2020-07-23 14:33:26 UTC (rev 264761)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp	2020-07-23 14:55:19 UTC (rev 264762)
@@ -110,7 +110,7 @@
             GST_WARNING("Track %d got sample with no buffer.", m_index);
             continue;
         }
-        auto mappedBuffer = GstMappedBuffer::create(buffer, GST_MAP_READ);
+        GstMappedBuffer mappedBuffer(buffer, GST_MAP_READ);
         ASSERT(mappedBuffer);
         if (!mappedBuffer) {
             GST_WARNING("Track %d unable to map buffer.", m_index);
@@ -117,9 +117,9 @@
             continue;
         }
 
-        GST_INFO("Track %d parsing sample: %.*s", m_index, static_cast<int>(mappedBuffer->size()),
-            reinterpret_cast<char*>(mappedBuffer->data()));
-        client()->parseWebVTTCueData(reinterpret_cast<char*>(mappedBuffer->data()), mappedBuffer->size());
+        GST_INFO("Track %d parsing sample: %.*s", m_index, static_cast<int>(mappedBuffer.size()),
+            reinterpret_cast<char*>(mappedBuffer.data()));
+        client()->parseWebVTTCueData(reinterpret_cast<char*>(mappedBuffer.data()), mappedBuffer.size());
     }
 }
 

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/eme/CDMProxyThunder.cpp (264761 => 264762)


--- trunk/Source/WebCore/platform/graphics/gstreamer/eme/CDMProxyThunder.cpp	2020-07-23 14:33:26 UTC (rev 264761)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/eme/CDMProxyThunder.cpp	2020-07-23 14:55:19 UTC (rev 264762)
@@ -46,13 +46,13 @@
 
 BoxPtr<OpenCDMSession> CDMProxyThunder::getDecryptionSession(const DecryptionContext& in) const
 {
-    auto mappedKeyID = GstMappedBuffer::create(in.keyIDBuffer, GST_MAP_READ);
+    GstMappedBuffer mappedKeyID(in.keyIDBuffer, GST_MAP_READ);
     if (!mappedKeyID) {
         GST_ERROR("Failed to map key ID buffer");
         return nullptr;
     }
 
-    auto keyID = mappedKeyID->createVector();
+    auto keyID = mappedKeyID.createVector();
 
     auto keyHandle = getOrWaitForKeyHandle(keyID);
     if (!keyHandle.hasValue() || !keyHandle.value()->isStatusCurrentlyValid())

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/eme/GStreamerEMEUtilities.h (264761 => 264762)


--- trunk/Source/WebCore/platform/graphics/gstreamer/eme/GStreamerEMEUtilities.h	2020-07-23 14:33:26 UTC (rev 264761)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/eme/GStreamerEMEUtilities.h	2020-07-23 14:55:19 UTC (rev 264762)
@@ -43,7 +43,7 @@
     InitData(const String& systemId, GstBuffer* initData)
         : m_systemId(systemId)
     {
-        auto mappedInitData = GstMappedBuffer::create(initData, GST_MAP_READ);
+        auto mappedInitData = GstMappedOwnedBuffer::create(initData);
         if (!mappedInitData) {
             GST_ERROR("cannot map %s protection data", systemId.utf8().data());
             ASSERT_NOT_REACHED();

Modified: trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitClearKeyDecryptorGStreamer.cpp (264761 => 264762)


--- trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitClearKeyDecryptorGStreamer.cpp	2020-07-23 14:33:26 UTC (rev 264761)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitClearKeyDecryptorGStreamer.cpp	2020-07-23 14:55:19 UTC (rev 264762)
@@ -128,44 +128,43 @@
         return false;
     }
 
-    auto mappedIVBuffer = WebCore::GstMappedBuffer::create(ivBuffer, GST_MAP_READ);
+    WebCore::GstMappedBuffer mappedIVBuffer(ivBuffer, GST_MAP_READ);
     if (!mappedIVBuffer) {
         GST_ERROR_OBJECT(self, "failed to map IV buffer");
         return false;
     }
 
-    auto mappedKeyIdBuffer = WebCore::GstMappedBuffer::create(keyIDBuffer, GST_MAP_READ);
+    WebCore::GstMappedBuffer mappedKeyIdBuffer(keyIDBuffer, GST_MAP_READ);
     if (!mappedKeyIdBuffer) {
         GST_ERROR_OBJECT(self, "Failed to map key id buffer");
         return false;
     }
 
-    auto mappedBuffer = WebCore::GstMappedBuffer::create(buffer, GST_MAP_READWRITE);
+    WebCore::GstMappedBuffer mappedBuffer(buffer, GST_MAP_READWRITE);
     if (!mappedBuffer) {
         GST_ERROR_OBJECT(self, "Failed to map buffer");
         return false;
     }
 
-    RefPtr<GstMappedBuffer> mappedSubsamplesBuffer;
     CDMProxyClearKey::cencDecryptContext context;
-    context.keyID = mappedKeyIdBuffer->data();
-    context.keyIDSizeInBytes = mappedKeyIdBuffer->size();
-    context.iv = mappedIVBuffer->data();
-    context.ivSizeInBytes = mappedIVBuffer->size();
-    context.encryptedBuffer = mappedBuffer->data();
-    context.encryptedBufferSizeInBytes = mappedBuffer->size();
+    context.keyID = mappedKeyIdBuffer.data();
+    context.keyIDSizeInBytes = mappedKeyIdBuffer.size();
+    context.iv = mappedIVBuffer.data();
+    context.ivSizeInBytes = mappedIVBuffer.size();
+    context.encryptedBuffer = mappedBuffer.data();
+    context.encryptedBufferSizeInBytes = mappedBuffer.size();
     context.numSubsamples = subsampleCount;
     if (!subsampleCount)
         context.subsamplesBuffer = nullptr;
     else {
         ASSERT(subsamplesBuffer);
-        mappedSubsamplesBuffer = WebCore::GstMappedBuffer::create(subsamplesBuffer, GST_MAP_READ);
+        WebCore::GstMappedBuffer mappedSubsamplesBuffer(subsamplesBuffer, GST_MAP_READ);
         if (!mappedSubsamplesBuffer) {
             GST_ERROR_OBJECT(self, "Failed to map subsample buffer");
             return false;
         }
-        context.subsamplesBuffer = mappedSubsamplesBuffer->data();
-        context.subsamplesBufferSizeInBytes = mappedSubsamplesBuffer->size();
+        context.subsamplesBuffer = mappedSubsamplesBuffer.data();
+        context.subsamplesBufferSizeInBytes = mappedSubsamplesBuffer.size();
     }
 
     return priv->cdmProxy->cencDecrypt(context);

Modified: trunk/Source/WebCore/platform/mediastream/gstreamer/MockRealtimeAudioSourceGStreamer.cpp (264761 => 264762)


--- trunk/Source/WebCore/platform/mediastream/gstreamer/MockRealtimeAudioSourceGStreamer.cpp	2020-07-23 14:33:26 UTC (rev 264761)
+++ trunk/Source/WebCore/platform/mediastream/gstreamer/MockRealtimeAudioSourceGStreamer.cpp	2020-07-23 14:55:19 UTC (rev 264762)
@@ -84,13 +84,13 @@
         GstAudioInfo* info = m_streamFormat->getInfo();
         GRefPtr<GstBuffer> buffer = adoptGRef(gst_buffer_new_allocate(nullptr, bipBopCount * m_streamFormat->bytesPerFrame(), nullptr));
         {
-            auto map = GstMappedBuffer::create(buffer.get(), GST_MAP_WRITE);
+            GstMappedBuffer map(buffer.get(), GST_MAP_WRITE);
 
             if (muted())
-                gst_audio_format_fill_silence(info->finfo, map->data(), map->size());
+                gst_audio_format_fill_silence(info->finfo, map.data(), map.size());
             else {
-                memcpy(map->data(), &m_bipBopBuffer[bipBopStart], sizeof(float) * bipBopCount);
-                addHum(s_HumVolume, s_HumFrequency, sampleRate(), m_samplesRendered, reinterpret_cast<float*>(map->data()), bipBopCount);
+                memcpy(map.data(), &m_bipBopBuffer[bipBopStart], sizeof(float) * bipBopCount);
+                addHum(s_HumVolume, s_HumFrequency, sampleRate(), m_samplesRendered, reinterpret_cast<float*>(map.data()), bipBopCount);
             }
         }
 

Modified: trunk/Source/WebCore/platform/mediastream/gstreamer/RealtimeOutgoingAudioSourceLibWebRTC.cpp (264761 => 264762)


--- trunk/Source/WebCore/platform/mediastream/gstreamer/RealtimeOutgoingAudioSourceLibWebRTC.cpp	2020-07-23 14:33:26 UTC (rev 264761)
+++ trunk/Source/WebCore/platform/mediastream/gstreamer/RealtimeOutgoingAudioSourceLibWebRTC.cpp	2020-07-23 14:55:19 UTC (rev 264762)
@@ -113,9 +113,9 @@
         if (isSilenced())
             gst_audio_format_fill_silence(m_outputStreamDescription->getInfo()->finfo, m_audioBuffer.data(), outBufferSize);
         else {
-            auto inMap = GstMappedBuffer::create(inBuffer.get(), GST_MAP_READ);
+            GstMappedBuffer inMap(inBuffer.get(), GST_MAP_READ);
 
-            gpointer in[1] = { inMap->data() };
+            gpointer in[1] = { inMap.data() };
             gpointer out[1] = { m_audioBuffer.data() };
             if (!gst_audio_converter_samples(m_sampleConverter.get(), static_cast<GstAudioConverterFlags>(0), in, inChunkSampleCount, out, outChunkSampleCount)) {
                 GST_ERROR("Could not convert samples.");

Modified: trunk/Source/WebCore/platform/mediastream/gstreamer/RealtimeOutgoingVideoSourceLibWebRTC.cpp (264761 => 264762)


--- trunk/Source/WebCore/platform/mediastream/gstreamer/RealtimeOutgoingVideoSourceLibWebRTC.cpp	2020-07-23 14:33:26 UTC (rev 264761)
+++ trunk/Source/WebCore/platform/mediastream/gstreamer/RealtimeOutgoingVideoSourceLibWebRTC.cpp	2020-07-23 14:55:19 UTC (rev 264762)
@@ -83,8 +83,8 @@
     GRefPtr<GstBuffer> buffer = adoptGRef(gst_buffer_new_allocate(nullptr, info.size, nullptr));
     GRefPtr<GstCaps> caps = adoptGRef(gst_video_info_to_caps(&info));
 
-    auto map = GstMappedBuffer::create(buffer.get(), GST_MAP_WRITE);
-    memset(map->data(), 0, info.size);
+    GstMappedBuffer map(buffer.get(), GST_MAP_WRITE);
+    memset(map.data(), 0, info.size);
 
     return GStreamerVideoFrameLibWebRTC::create(gst_sample_new(buffer.get(), caps.get(), NULL, NULL));
 }

Modified: trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoEncoderFactory.cpp (264761 => 264762)


--- trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoEncoderFactory.cpp	2020-07-23 14:33:26 UTC (rev 264761)
+++ trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoEncoderFactory.cpp	2020-07-23 14:55:19 UTC (rev 264762)
@@ -322,21 +322,21 @@
     virtual void Fragmentize(webrtc::EncodedImage* encodedImage, std::unique_ptr<uint8_t[]>* encodedImageBuffer,
         size_t* bufferSize, GstBuffer* buffer, webrtc::RTPFragmentationHeader* fragmentationInfo)
     {
-        auto map = GstMappedBuffer::create(buffer, GST_MAP_READ);
+        GstMappedBuffer map(buffer, GST_MAP_READ);
 
-        if (*bufferSize < map->size()) {
-            encodedImage->set_size(map->size());
-            encodedImage->set_buffer(new uint8_t[map->size()], map->size());
+        if (*bufferSize < map.size()) {
+            encodedImage->set_size(map.size());
+            encodedImage->set_buffer(new uint8_t[map.size()], map.size());
             encodedImageBuffer->reset(encodedImage->data());
-            *bufferSize = map->size();
+            *bufferSize = map.size();
         }
 
-        memcpy(encodedImage->data(), map->data(), map->size());
-        encodedImage->set_size(map->size());
+        memcpy(encodedImage->data(), map.data(), map.size());
+        encodedImage->set_size(map.size());
 
         fragmentationInfo->VerifyAndAllocateFragmentationHeader(1);
         fragmentationInfo->fragmentationOffset[0] = 0;
-        fragmentationInfo->fragmentationLength[0] = map->size();
+        fragmentationInfo->fragmentationLength[0] = map.size();
     }
 
     virtual const gchar* Name() = 0;
@@ -399,9 +399,9 @@
         std::vector<GstH264NalUnit> nals;
 
         const uint8_t startCode[4] = { 0, 0, 0, 1 };
-        auto map = GstMappedBuffer::create(gstbuffer, GST_MAP_READ);
+        GstMappedBuffer map(gstbuffer, GST_MAP_READ);
         while (parserResult == GST_H264_PARSER_OK) {
-            parserResult = gst_h264_parser_identify_nalu(m_parser, map->data(), offset, map->size(), &nalu);
+            parserResult = gst_h264_parser_identify_nalu(m_parser, map.data(), offset, map.size(), &nalu);
 
             nalu.sc_offset = offset;
             nalu.offset = offset + sizeof(startCode);
@@ -417,7 +417,7 @@
             encodedImage->set_size(requiredSize);
             encodedImage->set_buffer(new uint8_t[requiredSize], requiredSize);
             encodedImageBuffer->reset(encodedImage->data());
-            *bufferSize = map->size();
+            *bufferSize = map.size();
         }
 
         // Iterate nal units and fill the Fragmentation info.
@@ -426,15 +426,15 @@
         encodedImage->set_size(0);
         for (std::vector<GstH264NalUnit>::iterator nal = nals.begin(); nal != nals.end(); ++nal, fragmentIndex++) {
 
-            ASSERT(map->data()[nal->sc_offset + 0] == startCode[0]);
-            ASSERT(map->data()[nal->sc_offset + 1] == startCode[1]);
-            ASSERT(map->data()[nal->sc_offset + 2] == startCode[2]);
-            ASSERT(map->data()[nal->sc_offset + 3] == startCode[3]);
+            ASSERT(map.data()[nal->sc_offset + 0] == startCode[0]);
+            ASSERT(map.data()[nal->sc_offset + 1] == startCode[1]);
+            ASSERT(map.data()[nal->sc_offset + 2] == startCode[2]);
+            ASSERT(map.data()[nal->sc_offset + 3] == startCode[3]);
 
             fragmentationHeader->fragmentationOffset[fragmentIndex] = nal->offset;
             fragmentationHeader->fragmentationLength[fragmentIndex] = nal->size;
 
-            memcpy(encodedImage->data() + encodedImage->size(), &map->data()[nal->sc_offset],
+            memcpy(encodedImage->data() + encodedImage->size(), &map.data()[nal->sc_offset],
                 sizeof(startCode) + nal->size);
             encodedImage->set_size(nal->size + sizeof(startCode));
         }

Modified: trunk/Tools/ChangeLog (264761 => 264762)


--- trunk/Tools/ChangeLog	2020-07-23 14:33:26 UTC (rev 264761)
+++ trunk/Tools/ChangeLog	2020-07-23 14:55:19 UTC (rev 264762)
@@ -1,3 +1,16 @@
+2020-07-23  Xabier Rodriguez Calvar  <calva...@igalia.com>
+
+        [GStreamer] gst_buffer_unmap: assertion 'GST_IS_BUFFER (buffer)' failed
+        https://bugs.webkit.org/show_bug.cgi?id=213364
+
+        Reviewed by Philippe Normand.
+
+        Reworked tests for GstMappedBuffer and added tests for
+        GstMappedOwnedBuffer.
+
+        * TestWebKitAPI/Tests/WebCore/gstreamer/GstMappedBuffer.cpp:
+        (TestWebKitAPI::TEST_F):
+
 2020-07-23  Aakash Jain  <aakash_j...@apple.com>
 
         [ews] Add support to send emails in ews

Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/gstreamer/GstMappedBuffer.cpp (264761 => 264762)


--- trunk/Tools/TestWebKitAPI/Tests/WebCore/gstreamer/GstMappedBuffer.cpp	2020-07-23 14:33:26 UTC (rev 264761)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/gstreamer/GstMappedBuffer.cpp	2020-07-23 14:55:19 UTC (rev 264762)
@@ -40,15 +40,15 @@
 TEST_F(GStreamerTest, mappedBufferBasics)
 {
     GRefPtr<GstBuffer> buf = adoptGRef(gst_buffer_new_allocate(nullptr, 64, nullptr));
-    auto mappedBuf = GstMappedBuffer::create(buf.get(), GST_MAP_READ);
+    GstMappedBuffer mappedBuf(buf, GST_MAP_READ);
     ASSERT_TRUE(mappedBuf);
-    EXPECT_EQ(mappedBuf->size(), 64);
+    EXPECT_EQ(mappedBuf.size(), 64);
 
-    auto mappedBuf2 = GstMappedBuffer::create(buf.get(), GST_MAP_READ);
+    GstMappedBuffer mappedBuf2(buf, GST_MAP_READ);
     ASSERT_TRUE(mappedBuf2);
-    EXPECT_EQ(*mappedBuf, *mappedBuf2);
-    EXPECT_EQ(buf.get(), *mappedBuf);
-    EXPECT_EQ(*mappedBuf2, buf.get());
+    EXPECT_EQ(mappedBuf, mappedBuf2);
+    EXPECT_EQ(buf.get(), mappedBuf);
+    EXPECT_EQ(mappedBuf2, buf.get());
 }
 
 TEST_F(GStreamerTest, mappedBufferReadSanity)
@@ -56,11 +56,10 @@
     gpointer memory = g_malloc(16);
     memset(memory, 'x', 16);
     GRefPtr<GstBuffer> buf = adoptGRef(gst_buffer_new_wrapped(memory, 16));
-    auto mappedBuf = GstMappedBuffer::create(buf.get(), GST_MAP_READ);
+    GstMappedBuffer mappedBuf(buf, GST_MAP_READ);
     ASSERT_TRUE(mappedBuf);
-    EXPECT_EQ(mappedBuf->size(), 16);
-    EXPECT_EQ(memcmp(memory, mappedBuf->data(), 16), 0);
-    EXPECT_EQ(memcmp(memory, mappedBuf->createSharedBuffer()->data(), 16), 0);
+    EXPECT_EQ(mappedBuf.size(), 16);
+    EXPECT_EQ(memcmp(memory, mappedBuf.data(), 16), 0);
 }
 
 TEST_F(GStreamerTest, mappedBufferWriteSanity)
@@ -69,18 +68,47 @@
     memset(memory, 'x', 16);
     GRefPtr<GstBuffer> buf = adoptGRef(gst_buffer_new_wrapped(memory, 16));
 
-    auto mappedBuf = GstMappedBuffer::create(buf.get(), GST_MAP_WRITE);
+    GstMappedBuffer mappedBuf(buf.get(), GST_MAP_WRITE);
     ASSERT_TRUE(mappedBuf);
+    EXPECT_EQ(mappedBuf.size(), 16);
+    memset(mappedBuf.data(), 'y', mappedBuf.size());
+
+    EXPECT_EQ(memcmp(memory, mappedBuf.data(), 16), 0);
+}
+
+TEST_F(GStreamerTest, mappedBufferDoesNotAddExtraRefs)
+{
+    // It is important not to ref the passed GStreamer buffers, if we
+    // do so, then in the case of writable buffers, they can become
+    // unwritable, even though we are the sole owners. We also don't
+    // want to take ownership of the buffer from the user-code, since
+    // for transformInPlace use-cases, that would break.
+    GRefPtr<GstBuffer> buf = adoptGRef(gst_buffer_new());
+
+    ASSERT_EQ(GST_OBJECT_REFCOUNT(buf.get()), 1);
+
+    GstMappedBuffer mappedBuf(buf, GST_MAP_READWRITE);
+    ASSERT_TRUE(mappedBuf);
+
+    ASSERT_EQ(GST_OBJECT_REFCOUNT(buf.get()), 1);
+}
+
+TEST_F(GStreamerTest, mappedOwnedBufferReadSanity)
+{
+    gpointer memory = g_malloc(16);
+    memset(memory, 'x', 16);
+    GRefPtr<GstBuffer> buf = adoptGRef(gst_buffer_new_wrapped(memory, 16));
+    auto mappedBuf = GstMappedOwnedBuffer::create(buf);
+    ASSERT_TRUE(mappedBuf);
     EXPECT_EQ(mappedBuf->size(), 16);
-    memset(mappedBuf->data(), 'y', mappedBuf->size());
-
     EXPECT_EQ(memcmp(memory, mappedBuf->data(), 16), 0);
+    EXPECT_EQ(memcmp(memory, mappedBuf->createSharedBuffer()->data(), 16), 0);
 }
 
-TEST_F(GStreamerTest, mappedBufferCachesSharedBuffers)
+TEST_F(GStreamerTest, mappedOwnedBufferCachesSharedBuffers)
 {
     GRefPtr<GstBuffer> buf = adoptGRef(gst_buffer_new_allocate(nullptr, 64, nullptr));
-    auto mappedBuf = GstMappedBuffer::create(buf.get(), GST_MAP_READ);
+    auto mappedBuf = GstMappedOwnedBuffer::create(buf);
     ASSERT_TRUE(mappedBuf);
     auto sharedBuf = mappedBuf->createSharedBuffer();
     // We expect the same data pointer wrapped by shared buffer, no
@@ -88,20 +116,21 @@
     EXPECT_EQ(sharedBuf->data(), mappedBuf->createSharedBuffer()->data());
 }
 
-TEST_F(GStreamerTest, mappedBufferDoesNotAddExtraRefs)
+TEST_F(GStreamerTest, mappedOwnedBufferDoesAddsExtraRefs)
 {
-    // It is important not to ref the passed GStreamer buffers, if we
-    // do so, then in the case of writable buffers, they can become
-    // unwritable, even though we are the sole owners. We also don't
-    // want to take ownership of the buffer from the user-code, since
-    // for transformInPlace use-cases, that would break.
+    // GstMappedOwnedBuffer needs to bump the buffer reference count
+    // so that it is sure that the buffer outlives the mapped buffer.
     GRefPtr<GstBuffer> buf = adoptGRef(gst_buffer_new());
 
     ASSERT_EQ(GST_OBJECT_REFCOUNT(buf.get()), 1);
 
-    auto mappedBuf = GstMappedBuffer::create(buf.get(), GST_MAP_READWRITE);
-    ASSERT_TRUE(mappedBuf);
+    {
+        auto mappedBuf = GstMappedOwnedBuffer::create(buf);
+        ASSERT_TRUE(mappedBuf);
 
+        ASSERT_EQ(GST_OBJECT_REFCOUNT(buf.get()), 2);
+    }
+
     ASSERT_EQ(GST_OBJECT_REFCOUNT(buf.get()), 1);
 }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to