Title: [233796] trunk/Source/WebCore
Revision
233796
Author
ctur...@igalia.com
Date
2018-07-13 01:10:51 -0700 (Fri, 13 Jul 2018)

Log Message

[GStreamer] Add GstBufferMapped abstraction
https://bugs.webkit.org/show_bug.cgi?id=187600

Reviewed by Xabier Rodriguez-Calvar.

There is a similar abstraction called `mapGstBuffer` and friends,
which have a slightly different use-case: wanting a buffer that is
mapped for a longer lifetime without have to keep track of the map
infos separately. They could be subsumed by this abstraction, but
everytime they need to write to the buffer, they'd have to remap
the memory blocks.

This abstraction is more for one-short reads and writes saving the user
from remembering to unmap the buffer and having to manage to
auxiliary GstMapInfo structures.

* platform/graphics/gstreamer/GStreamerCommon.h:
(WebCore::GstMappedBuffer::GstMappedBuffer):
(WebCore::GstMappedBuffer::~GstMappedBuffer):
(WebCore::GstMappedBuffer::data):
(WebCore::GstMappedBuffer::size const):
(WebCore::GstMappedBuffer::operator bool const):
* platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp:
(WebCore::InbandTextTrackPrivateGStreamer::notifyTrackOfSample):
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp:
(WebCore::MediaPlayerPrivateGStreamerBase::handleSyncMessage):
(WebCore::MediaPlayerPrivateGStreamerBase::initializationDataEncountered):
* platform/graphics/gstreamer/eme/WebKitClearKeyDecryptorGStreamer.cpp:
(webKitMediaClearKeyDecryptorSetupCipher):
(webKitMediaClearKeyDecryptorDecrypt):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (233795 => 233796)


--- trunk/Source/WebCore/ChangeLog	2018-07-13 07:04:11 UTC (rev 233795)
+++ trunk/Source/WebCore/ChangeLog	2018-07-13 08:10:51 UTC (rev 233796)
@@ -1,3 +1,36 @@
+2018-07-13  Charlie Turner  <ctur...@igalia.com>
+
+        [GStreamer] Add GstBufferMapped abstraction
+        https://bugs.webkit.org/show_bug.cgi?id=187600
+
+        Reviewed by Xabier Rodriguez-Calvar.
+
+        There is a similar abstraction called `mapGstBuffer` and friends,
+        which have a slightly different use-case: wanting a buffer that is
+        mapped for a longer lifetime without have to keep track of the map
+        infos separately. They could be subsumed by this abstraction, but
+        everytime they need to write to the buffer, they'd have to remap
+        the memory blocks.
+
+        This abstraction is more for one-short reads and writes saving the user
+        from remembering to unmap the buffer and having to manage to
+        auxiliary GstMapInfo structures.
+
+        * platform/graphics/gstreamer/GStreamerCommon.h:
+        (WebCore::GstMappedBuffer::GstMappedBuffer):
+        (WebCore::GstMappedBuffer::~GstMappedBuffer):
+        (WebCore::GstMappedBuffer::data):
+        (WebCore::GstMappedBuffer::size const):
+        (WebCore::GstMappedBuffer::operator bool const):
+        * platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp:
+        (WebCore::InbandTextTrackPrivateGStreamer::notifyTrackOfSample):
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp:
+        (WebCore::MediaPlayerPrivateGStreamerBase::handleSyncMessage):
+        (WebCore::MediaPlayerPrivateGStreamerBase::initializationDataEncountered):
+        * platform/graphics/gstreamer/eme/WebKitClearKeyDecryptorGStreamer.cpp:
+        (webKitMediaClearKeyDecryptorSetupCipher):
+        (webKitMediaClearKeyDecryptorDecrypt):
+
 2018-07-12  Wenson Hsieh  <wenson_hs...@apple.com>
 
         Make it easier to hit the significant rendered text layout milestone on pages with main article elements

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


--- trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h	2018-07-13 07:04:11 UTC (rev 233795)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h	2018-07-13 08:10:51 UTC (rev 233796)
@@ -81,6 +81,35 @@
     return static_cast<GstClockTime>(toGstUnsigned64Time(mediaTime));
 }
 
+class GstMappedBuffer {
+    WTF_MAKE_NONCOPYABLE(GstMappedBuffer);
+public:
+    GstMappedBuffer(GstBuffer* buffer, GstMapFlags flags)
+        : m_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.
+    GstMappedBuffer(GstBuffer* buffer, int flags)
+        : GstMappedBuffer(buffer, static_cast<GstMapFlags>(flags)) { }
+
+    ~GstMappedBuffer()
+    {
+        if (m_isValid)
+            gst_buffer_unmap(m_buffer, &m_info);
+    }
+
+    uint8_t* data() { ASSERT(m_isValid); return static_cast<uint8_t*>(m_info.data); }
+    size_t size() const { ASSERT(m_isValid); return static_cast<size_t>(m_info.size); }
+
+    explicit operator bool() const { return m_isValid; }
+private:
+    GstBuffer* m_buffer;
+    GstMapInfo m_info;
+    bool m_isValid { false };
+};
+
 bool gstRegistryHasElementForMediaType(GList* elementFactories, const char* capsString);
 void connectSimpleBusMessageCallback(GstElement *pipeline);
 void disconnectSimpleBusMessageCallback(GstElement *pipeline);

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


--- trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp	2018-07-13 07:04:11 UTC (rev 233795)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp	2018-07-13 08:10:51 UTC (rev 233796)
@@ -112,18 +112,16 @@
             GST_WARNING("Track %d got sample with no buffer.", m_index);
             continue;
         }
-        GstMapInfo info;
-        gboolean ret = gst_buffer_map(buffer, &info, GST_MAP_READ);
-        ASSERT(ret);
-        if (!ret) {
+        GstMappedBuffer mappedBuffer(buffer, GST_MAP_READ);
+        ASSERT(mappedBuffer);
+        if (!mappedBuffer) {
             GST_WARNING("Track %d unable to map buffer.", m_index);
             continue;
         }
 
-        GST_INFO("Track %d parsing sample: %.*s", m_index, static_cast<int>(info.size),
-            reinterpret_cast<char*>(info.data));
-        client()->parseWebVTTCueData(reinterpret_cast<char*>(info.data), info.size);
-        gst_buffer_unmap(buffer, &info);
+        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/MediaPlayerPrivateGStreamerBase.cpp (233795 => 233796)


--- trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp	2018-07-13 07:04:11 UTC (rev 233795)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp	2018-07-13 08:10:51 UTC (rev 233796)
@@ -403,14 +403,14 @@
             GstBuffer* data = ""
             gst_event_parse_protection(event.get(), &eventKeySystemId, &data, nullptr);
 
-            GstMapInfo mapInfo;
-            if (!gst_buffer_map(data, &mapInfo, GST_MAP_READ)) {
+            GstMappedBuffer dataMapped(data, GST_MAP_READ);
+            if (!dataMapped) {
                 GST_WARNING("cannot map %s protection data", eventKeySystemId);
                 break;
             }
-            GST_TRACE("appending init data for %s of size %" G_GSIZE_FORMAT, eventKeySystemId, mapInfo.size);
-            GST_MEMDUMP("init data", reinterpret_cast<const unsigned char*>(mapInfo.data), mapInfo.size);
-            concatenatedInitDataChunks.append(mapInfo.data, mapInfo.size);
+            GST_TRACE("appending init data for %s of size %" G_GSIZE_FORMAT, eventKeySystemId, dataMapped.size());
+            GST_MEMDUMP("init data", reinterpret_cast<const unsigned char*>(dataMapped.data()), dataMapped.size());
+            concatenatedInitDataChunks.append(dataMapped.data(), dataMapped.size());
             ++concatenatedInitDataChunksNumber;
             eventKeySystemIdString = eventKeySystemId;
             if (streamEncryptionInformation.second.contains(eventKeySystemId)) {
@@ -417,7 +417,6 @@
                 GST_TRACE("considering init data handled for %s", eventKeySystemId);
                 m_handledProtectionEvents.add(GST_EVENT_SEQNUM(event.get()));
             }
-            gst_buffer_unmap(data, &mapInfo);
         }
 
         if (!concatenatedInitDataChunksNumber)
@@ -1230,16 +1229,15 @@
         return;
     }
 
-    GstMapInfo mapInfo;
-    if (!gst_buffer_map(data, &mapInfo, GST_MAP_READ)) {
+    GstMappedBuffer dataMapped(data, GST_MAP_READ);
+    if (!dataMapped) {
         GST_WARNING("cannot map %s protection data", eventKeySystemUUID);
         return;
     }
 
-    GST_TRACE("init data encountered for %s of size %" G_GSIZE_FORMAT, eventKeySystemUUID, mapInfo.size);
-    GST_MEMDUMP("init data", reinterpret_cast<const uint8_t*>(mapInfo.data), mapInfo.size);
-    InitData initData(reinterpret_cast<const uint8_t*>(mapInfo.data), mapInfo.size);
-    gst_buffer_unmap(data, &mapInfo);
+    GST_TRACE("init data encountered for %s of size %" G_GSIZE_FORMAT, eventKeySystemUUID, dataMapped.size());
+    GST_MEMDUMP("init data", reinterpret_cast<const uint8_t*>(dataMapped.data()), dataMapped.size());
+    InitData initData(reinterpret_cast<const uint8_t*>(dataMapped.data()), dataMapped.size());
 
     String eventKeySystemUUIDString = eventKeySystemUUID;
     RunLoop::main().dispatch([weakThis = makeWeakPtr(*this), eventKeySystemUUID = eventKeySystemUUIDString, initData] {

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


--- trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitClearKeyDecryptorGStreamer.cpp	2018-07-13 07:04:11 UTC (rev 233795)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitClearKeyDecryptorGStreamer.cpp	2018-07-13 08:10:51 UTC (rev 233796)
@@ -24,6 +24,7 @@
 
 #if ENABLE(ENCRYPTED_MEDIA) && USE(GSTREAMER)
 
+#include "GStreamerCommon.h"
 #include "GStreamerEMEUtilities.h"
 #include <gcrypt.h>
 #include <gst/base/gstbytereader.h>
@@ -158,21 +159,17 @@
     gcry_error_t error;
 
     GRefPtr<GstBuffer> keyBuffer;
-    {
-        GstMapInfo keyIDBufferMap;
-        if (!gst_buffer_map(keyIDBuffer, &keyIDBufferMap, GST_MAP_READ)) {
-            GST_ERROR_OBJECT(self, "Failed to map key ID buffer");
-            return false;
-        }
+    WebCore::GstMappedBuffer mappedKeyIdBuffer(keyIDBuffer, GST_MAP_READ);
+    if (!mappedKeyIdBuffer) {
+        GST_ERROR_OBJECT(self, "Failed to map key ID buffer");
+        return false;
+    }
 
-        for (auto& key : priv->keys) {
-            if (!gst_buffer_memcmp(key.keyID.get(), 0, keyIDBufferMap.data, keyIDBufferMap.size)) {
-                keyBuffer = key.keyValue;
-                break;
-            }
+    for (auto& key : priv->keys) {
+        if (!gst_buffer_memcmp(key.keyID.get(), 0, mappedKeyIdBuffer.data(), mappedKeyIdBuffer.size())) {
+            keyBuffer = key.keyValue;
+            break;
         }
-
-        gst_buffer_unmap(keyIDBuffer, &keyIDBufferMap);
     }
 
     if (!keyBuffer) {
@@ -186,15 +183,14 @@
         return false;
     }
 
-    GstMapInfo keyMap;
-    if (!gst_buffer_map(keyBuffer.get(), &keyMap, GST_MAP_READ)) {
+    WebCore::GstMappedBuffer mappedKeyBuffer(keyBuffer.get(), GST_MAP_READ);
+    if (!mappedKeyBuffer) {
         GST_ERROR_OBJECT(self, "Failed to map decryption key");
         return false;
     }
 
-    ASSERT(keyMap.size == CLEARKEY_SIZE);
-    error = gcry_cipher_setkey(priv->handle, keyMap.data, keyMap.size);
-    gst_buffer_unmap(keyBuffer.get(), &keyMap);
+    ASSERT(mappedKeyBuffer.size() == CLEARKEY_SIZE);
+    error = gcry_cipher_setkey(priv->handle, mappedKeyBuffer.data(), mappedKeyBuffer.size());
     if (error) {
         GST_ERROR_OBJECT(self, "gcry_cipher_setkey failed: %s", gpg_strerror(error));
         return false;
@@ -205,7 +201,6 @@
 
 static gboolean webKitMediaClearKeyDecryptorDecrypt(WebKitMediaCommonEncryptionDecrypt* self, GstBuffer* ivBuffer, GstBuffer* buffer, unsigned subSampleCount, GstBuffer* subSamplesBuffer)
 {
-    GstMapInfo ivMap;
     // Check ivBuffer isn't null.
     if (!ivBuffer) {
         GST_ERROR_OBJECT(self, "Error, the ivBuffer is null");
@@ -212,20 +207,20 @@
         return false;
     }
 
-    if (!gst_buffer_map(ivBuffer, &ivMap, GST_MAP_READ)) {
+    WebCore::GstMappedBuffer mappedIVBuffer(ivBuffer, GST_MAP_READ);
+    if (!mappedIVBuffer) {
         GST_ERROR_OBJECT(self, "Failed to map IV");
         return false;
     }
 
     uint8_t ctr[CLEARKEY_SIZE];
-    if (ivMap.size == 8) {
+    if (mappedIVBuffer.size() == 8) {
         memset(ctr + 8, 0, 8);
-        memcpy(ctr, ivMap.data, 8);
+        memcpy(ctr, mappedIVBuffer.data(), 8);
     } else {
-        ASSERT(ivMap.size == CLEARKEY_SIZE);
-        memcpy(ctr, ivMap.data, CLEARKEY_SIZE);
+        ASSERT(mappedIVBuffer.size() == CLEARKEY_SIZE);
+        memcpy(ctr, mappedIVBuffer.data(), CLEARKEY_SIZE);
     }
-    gst_buffer_unmap(ivBuffer, &ivMap);
 
     WebKitMediaClearKeyDecryptPrivate* priv = WEBKIT_MEDIA_CK_DECRYPT_GET_PRIVATE(WEBKIT_MEDIA_CK_DECRYPT(self));
     gcry_error_t cipherError = gcry_cipher_setctr(priv->handle, ctr, CLEARKEY_SIZE);
@@ -240,52 +235,48 @@
         return false;
     }
 
-    GstMapInfo map;
-    gboolean bufferMapped = gst_buffer_map(buffer, &map, static_cast<GstMapFlags>(GST_MAP_READWRITE));
-    if (!bufferMapped) {
+    WebCore::GstMappedBuffer mappedBuffer(buffer, GST_MAP_READWRITE);
+    if (!mappedBuffer) {
         GST_ERROR_OBJECT(self, "Failed to map buffer");
         return false;
     }
 
-    bool returnValue = true;
     GstByteReader* reader;
     unsigned position = 0;
     unsigned sampleIndex = 0;
-    GstMapInfo subSamplesMap;
 
     if (!subSampleCount) {
         // Full sample encryption.
-        GST_TRACE_OBJECT(self, "full sample encryption: %zu encrypted bytes", map.size);
+        GST_TRACE_OBJECT(self, "full sample encryption: %zu encrypted bytes", mappedBuffer.size());
 
         // Check if the buffer is empty.
-        if (map.size) {
-            cipherError = gcry_cipher_decrypt(priv->handle, map.data, map.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));
-                returnValue = false;
+                return false;
             }
         }
-        goto releaseBuffer;
+        return true;
     }
 
     // Check subSamplesBuffer isn't null.
     if (!subSamplesBuffer) {
         GST_ERROR_OBJECT(self, "Error, the subSampleBuffer is null");
-        returnValue = false;
-        goto releaseBuffer;
+        return false;
     }
 
     // Subsample encryption.
-    if (!gst_buffer_map(subSamplesBuffer, &subSamplesMap, GST_MAP_READ)) {
+    WebCore::GstMappedBuffer mappedSubSamplesBuffer(subSamplesBuffer, GST_MAP_READ);
+    if (!mappedSubSamplesBuffer) {
         GST_ERROR_OBJECT(self, "Failed to map subsample buffer");
-        returnValue = false;
-        goto releaseBuffer;
+        return false;
     }
 
-    reader = gst_byte_reader_new(subSamplesMap.data, subSamplesMap.size);
-    GST_DEBUG_OBJECT(self, "position: %d, size: %zu", position, map.size);
+    reader = gst_byte_reader_new(mappedSubSamplesBuffer.data(), mappedSubSamplesBuffer.size());
+    GST_DEBUG_OBJECT(self, "position: %d, size: %zu", position, mappedBuffer.size());
 
-    while (position < map.size) {
+    while (position < mappedBuffer.size()) {
         guint16 nBytesClear = 0;
         guint32 nBytesEncrypted = 0;
 
@@ -293,35 +284,31 @@
             if (!gst_byte_reader_get_uint16_be(reader, &nBytesClear)
                 || !gst_byte_reader_get_uint32_be(reader, &nBytesEncrypted)) {
                 GST_DEBUG_OBJECT(self, "unsupported");
-                returnValue = false;
-                goto releaseSubsamples;
+                gst_byte_reader_free(reader);
+                return false;
             }
             sampleIndex++;
         } else {
             nBytesClear = 0;
-            nBytesEncrypted = map.size - position;
+            nBytesEncrypted = mappedBuffer.size() - position;
         }
 
-        GST_TRACE_OBJECT(self, "subsample index %u - %hu bytes clear (todo=%zu)", sampleIndex, nBytesClear, map.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 - %hu bytes encrypted (todo=%zu)", sampleIndex, nBytesEncrypted, map.size - position);
-            cipherError = gcry_cipher_decrypt(priv->handle, map.data + position, nBytesEncrypted, 0, 0);
+            GST_TRACE_OBJECT(self, "subsample index %u - %hu 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));
-                returnValue = false;
-                goto releaseSubsamples;
+                gst_byte_reader_free(reader);
+                return false;
             }
             position += nBytesEncrypted;
         }
     }
-releaseSubsamples:
+
     gst_byte_reader_free(reader);
-    gst_buffer_unmap(subSamplesBuffer, &subSamplesMap);
-
-releaseBuffer:
-    gst_buffer_unmap(buffer, &map);
-    return returnValue;
+    return true;
 }
 
 static void webKitMediaClearKeyDecryptorReleaseCipher(WebKitMediaCommonEncryptionDecrypt* self)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to