Diff
Modified: trunk/Source/WebCore/ChangeLog (239920 => 239921)
--- trunk/Source/WebCore/ChangeLog 2019-01-14 10:59:06 UTC (rev 239920)
+++ trunk/Source/WebCore/ChangeLog 2019-01-14 12:31:13 UTC (rev 239921)
@@ -1,3 +1,60 @@
+2019-01-14 Charlie Turner <ctur...@igalia.com>
+
+ [GStreamer] Add sharedBuffer utility to GstMappedBuffer, and a testsuite
+ https://bugs.webkit.org/show_bug.cgi?id=192977
+
+ Reviewed by Carlos Garcia Campos.
+
+ Add a utility method on GstMappedBuffer to return a SharedBuffer
+ view over the mapped data with no copies.
+
+ This patch also introduces a new gstreamer port API test
+ directory, and includes some tests for GstMappedBuffer.
+
+ New tests in the API section.
+
+ * platform/SharedBuffer.cpp: Add a new overload for
+ GstMappedBuffer that allows sharing the mapped GStreamer buffers
+ with zero copies.
+ (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): Update to new
+ API.
+ * platform/graphics/gstreamer/GStreamerCommon.cpp:
+ (WebCore::GstMappedBuffer::createSharedBuffer): Return a shared
+ buffer sharing this mapped buffer. The buffer must be shareable to
+ use this method.
+ * platform/graphics/gstreamer/GStreamerCommon.h:
+ (WebCore::GstMappedBuffer::create): Make GstMappedBuffer RefCounted
+ (WebCore::GstMappedBuffer::~GstMappedBuffer):
+ (WebCore::GstMappedBuffer::data):
+ (WebCore::GstMappedBuffer::data const):
+ (WebCore::GstMappedBuffer::size const):
+ (WebCore::GstMappedBuffer::isSharable const): New predicate to
+ check whether this buffer can be shared (i.e., is not writable)
+ (WebCore::GstMappedBuffer::GstMappedBuffer):
+ (WebCore::GstMappedBuffer::operator bool const): Deleted.
+ * platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp:
+ (WebCore::InbandTextTrackPrivateGStreamer::notifyTrackOfSample):
+ Update to use new API.
+ * platform/graphics/gstreamer/eme/GStreamerEMEUtilities.h:
+ (WebCore::InitData::InitData): Ditto.
+ * platform/graphics/gstreamer/eme/WebKitClearKeyDecryptorGStreamer.cpp:
+ (webKitMediaClearKeyDecryptorFindAndSetKey): Ditto.
+ (webKitMediaClearKeyDecryptorDecrypt): Ditto.
+ * platform/mediastream/gstreamer/MockGStreamerAudioCaptureSource.cpp:
+ (WebCore::WrappedMockRealtimeAudioSource::render): Ditto.
+ * platform/mediastream/gstreamer/RealtimeOutgoingAudioSourceLibWebRTC.cpp:
+ (WebCore::RealtimeOutgoingAudioSourceLibWebRTC::pullAudioData): Ditto.
+ * platform/mediastream/gstreamer/RealtimeOutgoingVideoSourceLibWebRTC.cpp:
+ (WebCore::RealtimeOutgoingVideoSourceLibWebRTC::createBlackFrame): Ditto.
+ * platform/mediastream/libwebrtc/GStreamerVideoEncoderFactory.cpp:
+ (WebCore::GStreamerVideoEncoder::Fragmentize): Ditto.
+
2019-01-14 Karl Leplat <karl.leplat_...@softathome.com>
[GTK][WPE] Graphic issue with invalidations on composited layers with subpixel positions
Modified: trunk/Source/WebCore/platform/SharedBuffer.cpp (239920 => 239921)
--- trunk/Source/WebCore/platform/SharedBuffer.cpp 2019-01-14 10:59:06 UTC (rev 239920)
+++ trunk/Source/WebCore/platform/SharedBuffer.cpp 2019-01-14 12:31:13 UTC (rev 239921)
@@ -54,6 +54,20 @@
append(WTFMove(data));
}
+#if USE(GSTREAMER)
+Ref<SharedBuffer> SharedBuffer::create(GstMappedBuffer& mappedBuffer)
+{
+ ASSERT(mappedBuffer.isSharable());
+ return adoptRef(*new SharedBuffer(mappedBuffer));
+}
+
+SharedBuffer::SharedBuffer(GstMappedBuffer& mappedBuffer)
+ : m_size(mappedBuffer.size())
+{
+ m_segments.append({0, DataSegment::create(&mappedBuffer)});
+}
+#endif
+
RefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String& filePath)
{
bool mappingSuccess;
@@ -211,6 +225,9 @@
#if USE(GLIB)
[](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()); },
+#endif
[](const FileSystem::MappedFileData& data) { return reinterpret_cast<const char*>(data.data()); }
);
return WTF::visit(visitor, m_immutableData);
@@ -284,6 +301,9 @@
#if USE(GLIB)
[](const GRefPtr<GBytes>& data) { return g_bytes_get_size(data.get()); },
#endif
+#if USE(GSTREAMER)
+ [](const RefPtr<GstMappedBuffer>& data) { return data->size(); },
+#endif
[](const FileSystem::MappedFileData& data) { return data.size(); }
);
return WTF::visit(visitor, m_immutableData);
Modified: trunk/Source/WebCore/platform/SharedBuffer.h (239920 => 239921)
--- trunk/Source/WebCore/platform/SharedBuffer.h 2019-01-14 10:59:06 UTC (rev 239920)
+++ trunk/Source/WebCore/platform/SharedBuffer.h 2019-01-14 12:31:13 UTC (rev 239921)
@@ -48,6 +48,10 @@
typedef struct _GBytes GBytes;
#endif
+#if USE(GSTREAMER)
+#include "GStreamerCommon.h"
+#endif
+
#if USE(FOUNDATION)
OBJC_CLASS NSArray;
OBJC_CLASS NSData;
@@ -88,6 +92,9 @@
static Ref<SharedBuffer> create(GBytes*);
#endif
+#if USE(GSTREAMER)
+ static Ref<SharedBuffer> create(GstMappedBuffer&);
+#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.
// FIXME: Audit the call sites of this function and replace them with iteration if possible.
@@ -126,6 +133,9 @@
#if USE(GLIB)
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))); }
+#endif
static Ref<DataSegment> create(FileSystem::MappedFileData&& data) { return adoptRef(*new DataSegment(WTFMove(data))); }
private:
@@ -143,6 +153,10 @@
DataSegment(GRefPtr<GBytes>&& data)
: m_immutableData(WTFMove(data)) { }
#endif
+#if USE(GSTREAMER)
+ DataSegment(RefPtr<GstMappedBuffer>&& data)
+ : m_immutableData(WTFMove(data)) { }
+#endif
DataSegment(FileSystem::MappedFileData&& data)
: m_immutableData(WTFMove(data)) { }
@@ -156,6 +170,9 @@
#if USE(GLIB)
GRefPtr<GBytes>,
#endif
+#if USE(GSTREAMER)
+ RefPtr<GstMappedBuffer>,
+#endif
FileSystem::MappedFileData> m_immutableData;
friend class SharedBuffer;
};
@@ -191,6 +208,9 @@
#if USE(GLIB)
explicit SharedBuffer(GBytes*);
#endif
+#if USE(GSTREAMER)
+ explicit SharedBuffer(GstMappedBuffer&);
+#endif
void combineIntoOneSegment() const;
Modified: trunk/Source/WebCore/platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp (239920 => 239921)
--- trunk/Source/WebCore/platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp 2019-01-14 10:59:06 UTC (rev 239920)
+++ trunk/Source/WebCore/platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp 2019-01-14 12:31:13 UTC (rev 239921)
@@ -327,7 +327,7 @@
Vector<GRefPtr<GstBuffer>> channelBufferList;
channelBufferList.reserveInitialCapacity(priv->sources.size());
- Vector<GstMappedBuffer> mappedBuffers;
+ Vector<RefPtr<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;
- GstMappedBuffer mappedBuffer(buffer.get(), GST_MAP_READWRITE);
+ auto mappedBuffer = GstMappedBuffer::create(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 (239920 => 239921)
--- trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.cpp 2019-01-14 10:59:06 UTC (rev 239920)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.cpp 2019-01-14 12:31:13 UTC (rev 239921)
@@ -25,6 +25,7 @@
#include "GstAllocatorFastMalloc.h"
#include "IntSize.h"
+#include "SharedBuffer.h"
#include <gst/audio/audio-info.h>
#include <gst/gst.h>
#include <mutex>
@@ -357,6 +358,15 @@
g_signal_connect(bus.get(), "message", G_CALLBACK(simpleBusMessageCallback), pipeline);
}
+Ref<SharedBuffer> GstMappedBuffer::createSharedBuffer()
+{
+ // 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);
}
+}
+
#endif // USE(GSTREAMER)
Modified: trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h (239920 => 239921)
--- trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h 2019-01-14 10:59:06 UTC (rev 239920)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h 2019-01-14 12:31:13 UTC (rev 239921)
@@ -27,10 +27,12 @@
#include <gst/video/video-format.h>
#include <gst/video/video-info.h>
#include <wtf/MediaTime.h>
+#include <wtf/ThreadSafeRefCounted.h>
namespace WebCore {
class IntSize;
+class SharedBuffer;
inline bool webkitGstCheckVersion(guint major, guint minor, guint micro)
{
@@ -77,44 +79,41 @@
return static_cast<GstClockTime>(toGstUnsigned64Time(mediaTime));
}
-class GstMappedBuffer {
- WTF_MAKE_NONCOPYABLE(GstMappedBuffer);
+class GstMappedBuffer : public ThreadSafeRefCounted<GstMappedBuffer> {
public:
-
- GstMappedBuffer(GstMappedBuffer&& other)
- : m_buffer(other.m_buffer)
- , m_info(other.m_info)
- , m_isValid(other.m_isValid)
+ static RefPtr<GstMappedBuffer> create(GstBuffer* buffer, GstMapFlags flags)
{
- other.m_isValid = false;
+ GstMapInfo info;
+ if (!gst_buffer_map(buffer, &info, flags))
+ return nullptr;
+ return adoptRef(new GstMappedBuffer(buffer, WTFMove(info)));
}
- GstMappedBuffer(GstBuffer* buffer, GstMapFlags flags)
- : m_buffer(buffer)
+ // 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)
{
- m_isValid = gst_buffer_map(m_buffer, &m_info, flags);
+ return GstMappedBuffer::create(buffer, static_cast<GstMapFlags>(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.
- GstMappedBuffer(GstBuffer* buffer, int flags)
- : GstMappedBuffer(buffer, static_cast<GstMapFlags>(flags)) { }
-
~GstMappedBuffer()
{
- if (m_isValid)
- gst_buffer_unmap(m_buffer, &m_info);
- m_isValid = false;
+ gst_buffer_unmap(m_buffer, &m_info);
}
- uint8_t* data() { ASSERT(m_isValid); return static_cast<uint8_t*>(m_info.data); }
- const uint8_t* data() const { ASSERT(m_isValid); return static_cast<uint8_t*>(m_info.data); }
+ 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();
- size_t size() const { ASSERT(m_isValid); return static_cast<size_t>(m_info.size); }
+private:
+ GstMappedBuffer(GstBuffer* buffer, GstMapInfo&& info)
+ : m_buffer(buffer)
+ , m_info(WTFMove(info))
+ {
+ }
- explicit operator bool() const { return m_isValid; }
-
-private:
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); }
@@ -121,7 +120,6 @@
GstBuffer* m_buffer { nullptr };
GstMapInfo m_info;
- bool m_isValid { false };
};
inline bool operator==(const GstMappedBuffer& a, const GstMappedBuffer& b)
Modified: trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp (239920 => 239921)
--- trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp 2019-01-14 10:59:06 UTC (rev 239920)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp 2019-01-14 12:31:13 UTC (rev 239921)
@@ -112,7 +112,7 @@
GST_WARNING("Track %d got sample with no buffer.", m_index);
continue;
}
- GstMappedBuffer mappedBuffer(buffer, GST_MAP_READ);
+ auto mappedBuffer = GstMappedBuffer::create(buffer, GST_MAP_READ);
ASSERT(mappedBuffer);
if (!mappedBuffer) {
GST_WARNING("Track %d unable to map buffer.", m_index);
@@ -119,9 +119,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/GStreamerEMEUtilities.h (239920 => 239921)
--- trunk/Source/WebCore/platform/graphics/gstreamer/eme/GStreamerEMEUtilities.h 2019-01-14 10:59:06 UTC (rev 239920)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/eme/GStreamerEMEUtilities.h 2019-01-14 12:31:13 UTC (rev 239921)
@@ -40,12 +40,12 @@
InitData(const String& systemId, GstBuffer* initData)
: m_systemId(systemId)
{
- GstMappedBuffer mappedInitData(initData, GST_MAP_READ);
+ auto mappedInitData = GstMappedBuffer::create(initData, GST_MAP_READ);
if (!mappedInitData) {
GST_ERROR("cannot map %s protection data", systemId.utf8().data());
ASSERT_NOT_REACHED();
}
- m_payload = SharedBuffer::create(mappedInitData.data(), mappedInitData.size());
+ m_payload = mappedInitData->createSharedBuffer();
}
void append(InitData&& initData)
Modified: trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitClearKeyDecryptorGStreamer.cpp (239920 => 239921)
--- trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitClearKeyDecryptorGStreamer.cpp 2019-01-14 10:59:06 UTC (rev 239920)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitClearKeyDecryptorGStreamer.cpp 2019-01-14 12:31:13 UTC (rev 239921)
@@ -150,11 +150,11 @@
return TRUE;
}
-static gboolean webKitMediaClearKeyDecryptorFindAndSetKey(WebKitMediaClearKeyDecryptPrivate* priv, const WebCore::GstMappedBuffer& keyIDBuffer)
+static gboolean webKitMediaClearKeyDecryptorFindAndSetKey(WebKitMediaClearKeyDecryptPrivate* priv, RefPtr<WebCore::GstMappedBuffer>&& keyIDBuffer)
{
GRefPtr<GstBuffer> keyBuffer;
for (auto& key : priv->keys) {
- if (key.keyID.get() == keyIDBuffer) {
+ if (key.keyID.get() == *keyIDBuffer) {
keyBuffer = key.keyValue;
break;
}
@@ -165,14 +165,14 @@
return false;
}
- WebCore::GstMappedBuffer mappedKeyValueBuffer(keyBuffer.get(), GST_MAP_READ);
+ auto mappedKeyValueBuffer = WebCore::GstMappedBuffer::create(keyBuffer.get(), GST_MAP_READ);
if (!mappedKeyValueBuffer) {
GST_ERROR_OBJECT(priv, "Failed to map decryption key");
return false;
}
- ASSERT(mappedKeyValueBuffer.size() == CLEARKEY_SIZE);
- if (gcry_error_t error = gcry_cipher_setkey(priv->handle, mappedKeyValueBuffer.data(), mappedKeyValueBuffer.size())) {
+ ASSERT(mappedKeyValueBuffer->size() == CLEARKEY_SIZE);
+ if (gcry_error_t error = gcry_cipher_setkey(priv->handle, mappedKeyValueBuffer->data(), mappedKeyValueBuffer->size())) {
GST_ERROR_OBJECT(priv, "gcry_cipher_setkey failed: %s", gpg_strerror(error));
return false;
}
@@ -188,7 +188,7 @@
return false;
}
- WebCore::GstMappedBuffer mappedIVBuffer(ivBuffer, GST_MAP_READ);
+ auto mappedIVBuffer = WebCore::GstMappedBuffer::create(ivBuffer, GST_MAP_READ);
if (!mappedIVBuffer) {
GST_ERROR_OBJECT(self, "Failed to map IV");
return false;
@@ -195,12 +195,12 @@
}
uint8_t ctr[CLEARKEY_SIZE];
- if (mappedIVBuffer.size() == 8) {
+ if (mappedIVBuffer->size() == 8) {
memset(ctr + 8, 0, 8);
- memcpy(ctr, mappedIVBuffer.data(), 8);
+ memcpy(ctr, mappedIVBuffer->data(), 8);
} else {
ASSERT(mappedIVBuffer.size() == CLEARKEY_SIZE);
- memcpy(ctr, mappedIVBuffer.data(), CLEARKEY_SIZE);
+ memcpy(ctr, mappedIVBuffer->data(), CLEARKEY_SIZE);
}
WebKitMediaClearKeyDecryptPrivate* priv = WEBKIT_MEDIA_CK_DECRYPT_GET_PRIVATE(WEBKIT_MEDIA_CK_DECRYPT(self));
@@ -216,19 +216,19 @@
return false;
}
- WebCore::GstMappedBuffer mappedKeyIdBuffer(keyIDBuffer, GST_MAP_READ);
+ auto mappedKeyIdBuffer = WebCore::GstMappedBuffer::create(keyIDBuffer, GST_MAP_READ);
if (!mappedKeyIdBuffer) {
GST_ERROR_OBJECT(self, "Failed to map key id buffer");
return false;
}
- WebCore::GstMappedBuffer mappedBuffer(buffer, GST_MAP_READWRITE);
+ auto mappedBuffer = WebCore::GstMappedBuffer::create(buffer, GST_MAP_READWRITE);
if (!mappedBuffer) {
GST_ERROR_OBJECT(self, "Failed to map buffer");
return false;
}
- webKitMediaClearKeyDecryptorFindAndSetKey(priv, mappedKeyIdBuffer);
+ webKitMediaClearKeyDecryptorFindAndSetKey(priv, WTFMove(mappedKeyIdBuffer));
unsigned position = 0;
unsigned sampleIndex = 0;
@@ -235,11 +235,11 @@
if (!subSampleCount) {
// Full sample encryption.
- GST_TRACE_OBJECT(self, "full sample encryption: %zu encrypted bytes", mappedBuffer.size());
+ GST_TRACE_OBJECT(self, "full sample encryption: %zu encrypted bytes", mappedBuffer->size());
// Check if the buffer is empty.
- if (mappedBuffer.size()) {
- cipherError = gcry_cipher_decrypt(priv->handle, mappedBuffer.data(), mappedBuffer.size(), 0, 0);
+ if (mappedBuffer->size()) {
+ cipherError = gcry_cipher_decrypt(priv->handle, mappedBuffer->data(), mappedBuffer->size(), 0, 0);
if (cipherError) {
GST_ERROR_OBJECT(self, "full sample decryption failed: %s", gpg_strerror(cipherError));
return false;
@@ -255,16 +255,16 @@
}
// Subsample encryption.
- WebCore::GstMappedBuffer mappedSubSamplesBuffer(subSamplesBuffer, GST_MAP_READ);
+ auto mappedSubSamplesBuffer = WebCore::GstMappedBuffer::create(subSamplesBuffer, GST_MAP_READ);
if (!mappedSubSamplesBuffer) {
GST_ERROR_OBJECT(self, "Failed to map subsample buffer");
return false;
}
- GUniquePtr<GstByteReader> reader(gst_byte_reader_new(mappedSubSamplesBuffer.data(), mappedSubSamplesBuffer.size()));
- GST_DEBUG_OBJECT(self, "position: %d, size: %zu", position, mappedBuffer.size());
+ GUniquePtr<GstByteReader> reader(gst_byte_reader_new(mappedSubSamplesBuffer->data(), mappedSubSamplesBuffer->size()));
+ GST_DEBUG_OBJECT(self, "position: %d, size: %zu", position, mappedBuffer->size());
- while (position < mappedBuffer.size()) {
+ while (position < mappedBuffer->size()) {
guint16 nBytesClear = 0;
guint32 nBytesEncrypted = 0;
@@ -277,14 +277,14 @@
sampleIndex++;
} else {
nBytesClear = 0;
- nBytesEncrypted = mappedBuffer.size() - position;
+ nBytesEncrypted = mappedBuffer->size() - position;
}
- GST_TRACE_OBJECT(self, "subsample index %u - %hu bytes clear (todo=%zu)", sampleIndex, nBytesClear, mappedBuffer.size() - position);
+ GST_TRACE_OBJECT(self, "subsample index %u - %hu bytes clear (todo=%zu)", sampleIndex, nBytesClear, mappedBuffer->size() - position);
position += nBytesClear;
if (nBytesEncrypted) {
- GST_TRACE_OBJECT(self, "subsample index %u - %u bytes encrypted (todo=%zu)", sampleIndex, nBytesEncrypted, mappedBuffer.size() - position);
- cipherError = gcry_cipher_decrypt(priv->handle, mappedBuffer.data() + position, nBytesEncrypted, 0, 0);
+ GST_TRACE_OBJECT(self, "subsample index %u - %u bytes encrypted (todo=%zu)", sampleIndex, nBytesEncrypted, mappedBuffer->size() - position);
+ cipherError = gcry_cipher_decrypt(priv->handle, mappedBuffer->data() + position, nBytesEncrypted, 0, 0);
if (cipherError) {
GST_ERROR_OBJECT(self, "sub sample index %u decryption failed: %s", sampleIndex, gpg_strerror(cipherError));
return false;
Modified: trunk/Source/WebCore/platform/mediastream/gstreamer/MockGStreamerAudioCaptureSource.cpp (239920 => 239921)
--- trunk/Source/WebCore/platform/mediastream/gstreamer/MockGStreamerAudioCaptureSource.cpp 2019-01-14 10:59:06 UTC (rev 239920)
+++ trunk/Source/WebCore/platform/mediastream/gstreamer/MockGStreamerAudioCaptureSource.cpp 2019-01-14 12:31:13 UTC (rev 239921)
@@ -78,13 +78,13 @@
GstBuffer* buffer = gst_buffer_new_allocate(nullptr, bipBopCount * m_streamFormat->bytesPerFrame(), nullptr);
{
- GstMappedBuffer map(buffer, GST_MAP_WRITE);
+ auto map = GstMappedBuffer::create(buffer, GST_MAP_WRITE);
if (!muted()) {
- memcpy(map.data(), &m_bipBopBuffer[bipBopStart], sizeof(float) * bipBopCount);
- addHum(s_HumVolume, s_HumFrequency, sampleRate(), m_samplesRendered, (float*)map.data(), bipBopCount);
+ memcpy(map->data(), &m_bipBopBuffer[bipBopStart], sizeof(float) * bipBopCount);
+ addHum(s_HumVolume, s_HumFrequency, sampleRate(), m_samplesRendered, (float*)map->data(), bipBopCount);
} else
- memset(map.data(), 0, sizeof(float) * bipBopCount);
+ memset(map->data(), 0, sizeof(float) * bipBopCount);
}
gst_app_src_push_buffer(GST_APP_SRC(m_src.get()), buffer);
Modified: trunk/Source/WebCore/platform/mediastream/gstreamer/RealtimeOutgoingAudioSourceLibWebRTC.cpp (239920 => 239921)
--- trunk/Source/WebCore/platform/mediastream/gstreamer/RealtimeOutgoingAudioSourceLibWebRTC.cpp 2019-01-14 10:59:06 UTC (rev 239920)
+++ trunk/Source/WebCore/platform/mediastream/gstreamer/RealtimeOutgoingAudioSourceLibWebRTC.cpp 2019-01-14 12:31:13 UTC (rev 239921)
@@ -114,9 +114,9 @@
if (isSilenced())
gst_audio_format_fill_silence(m_outputStreamDescription->getInfo()->finfo, m_audioBuffer.data(), outBufferSize);
else {
- GstMappedBuffer inMap(inBuffer.get(), GST_MAP_READ);
+ auto inMap = GstMappedBuffer::create(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 (239920 => 239921)
--- trunk/Source/WebCore/platform/mediastream/gstreamer/RealtimeOutgoingVideoSourceLibWebRTC.cpp 2019-01-14 10:59:06 UTC (rev 239920)
+++ trunk/Source/WebCore/platform/mediastream/gstreamer/RealtimeOutgoingVideoSourceLibWebRTC.cpp 2019-01-14 12:31:13 UTC (rev 239921)
@@ -86,8 +86,8 @@
GRefPtr<GstBuffer> buffer = adoptGRef(gst_buffer_new_allocate(nullptr, info.size, nullptr));
GRefPtr<GstCaps> caps = adoptGRef(gst_video_info_to_caps(&info));
- GstMappedBuffer map(buffer.get(), GST_MAP_WRITE);
- memset(map.data(), 0, info.size);
+ auto map = GstMappedBuffer::create(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 (239920 => 239921)
--- trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoEncoderFactory.cpp 2019-01-14 10:59:06 UTC (rev 239920)
+++ trunk/Source/WebCore/platform/mediastream/libwebrtc/GStreamerVideoEncoderFactory.cpp 2019-01-14 12:31:13 UTC (rev 239921)
@@ -342,22 +342,22 @@
virtual void Fragmentize(webrtc::EncodedImage* encodedImage, std::unique_ptr<uint8_t[]>* encodedImageBuffer,
size_t* bufferSize, GstBuffer* buffer, webrtc::RTPFragmentationHeader* fragmentationInfo)
{
- GstMappedBuffer map(buffer, GST_MAP_READ);
+ auto map = GstMappedBuffer::create(buffer, GST_MAP_READ);
- if (*bufferSize < map.size()) {
- encodedImage->_size = map.size();
+ if (*bufferSize < map->size()) {
+ encodedImage->_size = map->size();
encodedImage->_buffer = new uint8_t[encodedImage->_size];
encodedImageBuffer->reset(encodedImage->_buffer);
- *bufferSize = map.size();
+ *bufferSize = map->size();
}
- memcpy(encodedImage->_buffer, map.data(), map.size());
- encodedImage->_length = map.size();
- encodedImage->_size = map.size();
+ memcpy(encodedImage->_buffer, map->data(), map->size());
+ encodedImage->_length = map->size();
+ encodedImage->_size = map->size();
fragmentationInfo->VerifyAndAllocateFragmentationHeader(1);
fragmentationInfo->fragmentationOffset[0] = 0;
- fragmentationInfo->fragmentationLength[0] = map.size();
+ fragmentationInfo->fragmentationLength[0] = map->size();
fragmentationInfo->fragmentationPlType[0] = 0;
fragmentationInfo->fragmentationTimeDiff[0] = 0;
}
@@ -438,9 +438,9 @@
std::vector<GstH264NalUnit> nals;
const uint8_t startCode[4] = { 0, 0, 0, 1 };
- GstMappedBuffer map(gstbuffer, GST_MAP_READ);
+ auto map = GstMappedBuffer::create(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);
@@ -456,7 +456,7 @@
encodedImage->_size = requiredSize;
encodedImage->_buffer = new uint8_t[encodedImage->_size];
encodedImageBuffer->reset(encodedImage->_buffer);
- *bufferSize = map.size();
+ *bufferSize = map->size();
}
// Iterate nal units and fill the Fragmentation info.
@@ -465,15 +465,15 @@
encodedImage->_length = 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->_buffer + encodedImage->_length, &map.data()[nal->sc_offset],
+ memcpy(encodedImage->_buffer + encodedImage->_length, &map->data()[nal->sc_offset],
sizeof(startCode) + nal->size);
encodedImage->_length += nal->size + sizeof(startCode);
}
Modified: trunk/Tools/ChangeLog (239920 => 239921)
--- trunk/Tools/ChangeLog 2019-01-14 10:59:06 UTC (rev 239920)
+++ trunk/Tools/ChangeLog 2019-01-14 12:31:13 UTC (rev 239921)
@@ -1,5 +1,21 @@
2019-01-14 Charlie Turner <ctur...@igalia.com>
+ [GStreamer] Add sharedBuffer utility to GstMappedBuffer, and a testsuite
+ https://bugs.webkit.org/show_bug.cgi?id=192977
+
+ Reviewed by Carlos Garcia Campos.
+
+ * TestWebKitAPI/PlatformGTK.cmake: Build the new GStreamer test harness
+ * TestWebKitAPI/PlatformWPE.cmake: Ditto.
+ * TestWebKitAPI/Tests/WebCore/gstreamer/GStreamerTest.cpp: Added.
+ (TestWebKitAPI::GStreamerTest::SetUp):
+ (TestWebKitAPI::GStreamerTest::TearDown):
+ * TestWebKitAPI/Tests/WebCore/gstreamer/GStreamerTest.h: Added.
+ * TestWebKitAPI/Tests/WebCore/gstreamer/GstMappedBuffer.cpp: Added.
+ (TestWebKitAPI::TEST_F):
+
+2019-01-14 Charlie Turner <ctur...@igalia.com>
+
[WPE] Workaround for incorrect template specialization being selected when UChar=char16_t
https://bugs.webkit.org/show_bug.cgi?id=193332
Modified: trunk/Tools/TestWebKitAPI/PlatformGTK.cmake (239920 => 239921)
--- trunk/Tools/TestWebKitAPI/PlatformGTK.cmake 2019-01-14 10:59:06 UTC (rev 239920)
+++ trunk/Tools/TestWebKitAPI/PlatformGTK.cmake 2019-01-14 12:31:13 UTC (rev 239921)
@@ -25,6 +25,7 @@
include_directories(SYSTEM
${GDK3_INCLUDE_DIRS}
${GLIB_INCLUDE_DIRS}
+ ${GSTREAMER_INCLUDE_DIRS}
${GTK3_INCLUDE_DIRS}
${LIBSOUP_INCLUDE_DIRS}
)
@@ -93,6 +94,8 @@
${TESTWEBKITAPI_DIR}/Tests/WebCore/DNS.cpp
${TESTWEBKITAPI_DIR}/Tests/WebCore/FileMonitor.cpp
${TESTWEBKITAPI_DIR}/Tests/WebCore/FileSystem.cpp
+ ${TESTWEBKITAPI_DIR}/Tests/WebCore/gstreamer/GstMappedBuffer.cpp
+ ${TESTWEBKITAPI_DIR}/Tests/WebCore/gstreamer/GStreamerTest.cpp
${TESTWEBKITAPI_DIR}/Tests/WebCore/GridPosition.cpp
${TESTWEBKITAPI_DIR}/Tests/WebCore/HTMLParserIdioms.cpp
${TESTWEBKITAPI_DIR}/Tests/WebCore/LayoutUnit.cpp
Modified: trunk/Tools/TestWebKitAPI/PlatformWPE.cmake (239920 => 239921)
--- trunk/Tools/TestWebKitAPI/PlatformWPE.cmake 2019-01-14 10:59:06 UTC (rev 239920)
+++ trunk/Tools/TestWebKitAPI/PlatformWPE.cmake 2019-01-14 12:31:13 UTC (rev 239921)
@@ -23,6 +23,7 @@
include_directories(SYSTEM
${CAIRO_INCLUDE_DIRS}
${GLIB_INCLUDE_DIRS}
+ ${GSTREAMER_INCLUDE_DIRS}
${LIBSOUP_INCLUDE_DIRS}
${WPE_INCLUDE_DIRS}
${WPEBACKEND_FDO_INCLUDE_DIRS}
@@ -60,6 +61,8 @@
${TESTWEBKITAPI_DIR}/TestsController.cpp
${TESTWEBKITAPI_DIR}/Tests/WebCore/FileMonitor.cpp
${TESTWEBKITAPI_DIR}/Tests/WebCore/FileSystem.cpp
+ ${TESTWEBKITAPI_DIR}/Tests/WebCore/gstreamer/GstMappedBuffer.cpp
+ ${TESTWEBKITAPI_DIR}/Tests/WebCore/gstreamer/GStreamerTest.cpp
${TESTWEBKITAPI_DIR}/Tests/WebCore/HTMLParserIdioms.cpp
${TESTWEBKITAPI_DIR}/Tests/WebCore/LayoutUnit.cpp
${TESTWEBKITAPI_DIR}/Tests/WebCore/MIMETypeRegistry.cpp
Added: trunk/Tools/TestWebKitAPI/Tests/WebCore/gstreamer/GStreamerTest.cpp (0 => 239921)
--- trunk/Tools/TestWebKitAPI/Tests/WebCore/gstreamer/GStreamerTest.cpp (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/gstreamer/GStreamerTest.cpp 2019-01-14 12:31:13 UTC (rev 239921)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2018 Igalia, S.L.
+ * Copyright (C) 2018 Metrological Group B.V.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if USE(GSTREAMER)
+#include "GStreamerTest.h"
+
+#include <WebCore/GStreamerCommon.h>
+#include <gst/gst.h>
+
+using namespace WebCore;
+
+namespace TestWebKitAPI {
+
+void GStreamerTest::SetUp()
+{
+ if (!gst_is_initialized())
+ gst_init(nullptr, nullptr);
+}
+
+void GStreamerTest::TearDown()
+{
+ // It might be tempting to call gst_deinit() here. However, that
+ // will tear down the whole process from the GStreamer POV, and the
+ // seemingly symmetrical call to gst_init() will fail to
+ // initialize GStreamer correctly.
+}
+
+} // namespace TestWebKitAPI
+
+#endif // USE(GSTREAMER)
Added: trunk/Tools/TestWebKitAPI/Tests/WebCore/gstreamer/GStreamerTest.h (0 => 239921)
--- trunk/Tools/TestWebKitAPI/Tests/WebCore/gstreamer/GStreamerTest.h (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/gstreamer/GStreamerTest.h 2019-01-14 12:31:13 UTC (rev 239921)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2018 Igalia, S.L.
+ * Copyright (C) 2018 Metrological Group B.V.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if USE(GSTREAMER)
+
+namespace TestWebKitAPI {
+
+class GStreamerTest : public testing::Test {
+public:
+ void SetUp() override;
+ void TearDown() override;
+};
+
+} // namespace TestWebKitAPI
+
+#endif // USE(GSTREAMER)
Added: trunk/Tools/TestWebKitAPI/Tests/WebCore/gstreamer/GstMappedBuffer.cpp (0 => 239921)
--- trunk/Tools/TestWebKitAPI/Tests/WebCore/gstreamer/GstMappedBuffer.cpp (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/gstreamer/GstMappedBuffer.cpp 2019-01-14 12:31:13 UTC (rev 239921)
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2018 Igalia, S.L.
+ * Copyright (C) 2018 Metrological Group B.V.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if USE(GSTREAMER)
+
+#include "GStreamerTest.h"
+#include "SharedBuffer.h"
+#include "Test.h"
+#include <WebCore/GStreamerCommon.h>
+
+using namespace WebCore;
+
+namespace TestWebKitAPI {
+
+TEST_F(GStreamerTest, mappedBufferBasics)
+{
+ GRefPtr<GstBuffer> buf = adoptGRef(gst_buffer_new_allocate(nullptr, 64, nullptr));
+ auto mappedBuf = GstMappedBuffer::create(buf.get(), GST_MAP_READ);
+ ASSERT_TRUE(mappedBuf);
+ EXPECT_EQ(mappedBuf->size(), 64);
+
+ auto mappedBuf2 = GstMappedBuffer::create(buf.get(), GST_MAP_READ);
+ ASSERT_TRUE(mappedBuf2);
+ EXPECT_EQ(*mappedBuf, *mappedBuf2);
+ EXPECT_EQ(buf.get(), *mappedBuf);
+ EXPECT_EQ(*mappedBuf2, buf.get());
+}
+
+TEST_F(GStreamerTest, mappedBufferReadSanity)
+{
+ 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);
+ 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);
+}
+
+TEST_F(GStreamerTest, mappedBufferWriteSanity)
+{
+ 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_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, mappedBufferCachesSharedBuffers)
+{
+ GRefPtr<GstBuffer> buf = adoptGRef(gst_buffer_new_allocate(nullptr, 64, nullptr));
+ auto mappedBuf = GstMappedBuffer::create(buf.get(), GST_MAP_READ);
+ ASSERT_TRUE(mappedBuf);
+ auto sharedBuf = mappedBuf->createSharedBuffer();
+ // We expect the same data pointer wrapped by shared buffer, no
+ // copies need to be made.
+ EXPECT_EQ(sharedBuf->data(), mappedBuf->createSharedBuffer()->data());
+}
+
+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);
+
+ auto mappedBuf = GstMappedBuffer::create(buf.get(), GST_MAP_READWRITE);
+ ASSERT_TRUE(mappedBuf);
+
+ ASSERT_EQ(GST_OBJECT_REFCOUNT(buf.get()), 1);
+}
+
+} // namespace TestWebKitAPI
+
+#endif // USE(GSTREAMER)