Changeset 233796 in webkit


Ignore:
Timestamp:
Jul 13, 2018 1:10:51 AM (6 years ago)
Author:
cturner@igalia.com
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):

Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r233794 r233796  
     12018-07-13  Charlie Turner  <cturner@igalia.com>
     2
     3        [GStreamer] Add GstBufferMapped abstraction
     4        https://bugs.webkit.org/show_bug.cgi?id=187600
     5
     6        Reviewed by Xabier Rodriguez-Calvar.
     7
     8        There is a similar abstraction called `mapGstBuffer` and friends,
     9        which have a slightly different use-case: wanting a buffer that is
     10        mapped for a longer lifetime without have to keep track of the map
     11        infos separately. They could be subsumed by this abstraction, but
     12        everytime they need to write to the buffer, they'd have to remap
     13        the memory blocks.
     14
     15        This abstraction is more for one-short reads and writes saving the user
     16        from remembering to unmap the buffer and having to manage to
     17        auxiliary GstMapInfo structures.
     18
     19        * platform/graphics/gstreamer/GStreamerCommon.h:
     20        (WebCore::GstMappedBuffer::GstMappedBuffer):
     21        (WebCore::GstMappedBuffer::~GstMappedBuffer):
     22        (WebCore::GstMappedBuffer::data):
     23        (WebCore::GstMappedBuffer::size const):
     24        (WebCore::GstMappedBuffer::operator bool const):
     25        * platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp:
     26        (WebCore::InbandTextTrackPrivateGStreamer::notifyTrackOfSample):
     27        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp:
     28        (WebCore::MediaPlayerPrivateGStreamerBase::handleSyncMessage):
     29        (WebCore::MediaPlayerPrivateGStreamerBase::initializationDataEncountered):
     30        * platform/graphics/gstreamer/eme/WebKitClearKeyDecryptorGStreamer.cpp:
     31        (webKitMediaClearKeyDecryptorSetupCipher):
     32        (webKitMediaClearKeyDecryptorDecrypt):
     33
    1342018-07-12  Wenson Hsieh  <wenson_hsieh@apple.com>
    235
  • trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h

    r232589 r233796  
    8282}
    8383
     84class GstMappedBuffer {
     85    WTF_MAKE_NONCOPYABLE(GstMappedBuffer);
     86public:
     87    GstMappedBuffer(GstBuffer* buffer, GstMapFlags flags)
     88        : m_buffer(buffer)
     89    {
     90        m_isValid = gst_buffer_map(m_buffer, &m_info, flags);
     91    }
     92    // Unfortunately, GST_MAP_READWRITE is defined out of line from the MapFlags
     93    // enum as an int, and C++ is careful to not implicity convert it to an enum.
     94    GstMappedBuffer(GstBuffer* buffer, int flags)
     95        : GstMappedBuffer(buffer, static_cast<GstMapFlags>(flags)) { }
     96
     97    ~GstMappedBuffer()
     98    {
     99        if (m_isValid)
     100            gst_buffer_unmap(m_buffer, &m_info);
     101    }
     102
     103    uint8_t* data() { ASSERT(m_isValid); return static_cast<uint8_t*>(m_info.data); }
     104    size_t size() const { ASSERT(m_isValid); return static_cast<size_t>(m_info.size); }
     105
     106    explicit operator bool() const { return m_isValid; }
     107private:
     108    GstBuffer* m_buffer;
     109    GstMapInfo m_info;
     110    bool m_isValid { false };
     111};
     112
    84113bool gstRegistryHasElementForMediaType(GList* elementFactories, const char* capsString);
    85114void connectSimpleBusMessageCallback(GstElement *pipeline);
  • trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp

    r230625 r233796  
    113113            continue;
    114114        }
    115         GstMapInfo info;
    116         gboolean ret = gst_buffer_map(buffer, &info, GST_MAP_READ);
    117         ASSERT(ret);
    118         if (!ret) {
     115        GstMappedBuffer mappedBuffer(buffer, GST_MAP_READ);
     116        ASSERT(mappedBuffer);
     117        if (!mappedBuffer) {
    119118            GST_WARNING("Track %d unable to map buffer.", m_index);
    120119            continue;
    121120        }
    122121
    123         GST_INFO("Track %d parsing sample: %.*s", m_index, static_cast<int>(info.size),
    124             reinterpret_cast<char*>(info.data));
    125         client()->parseWebVTTCueData(reinterpret_cast<char*>(info.data), info.size);
    126         gst_buffer_unmap(buffer, &info);
     122        GST_INFO("Track %d parsing sample: %.*s", m_index, static_cast<int>(mappedBuffer.size()),
     123            reinterpret_cast<char*>(mappedBuffer.data()));
     124        client()->parseWebVTTCueData(reinterpret_cast<char*>(mappedBuffer.data()), mappedBuffer.size());
    127125    }
    128126}
  • trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp

    r233248 r233796  
    404404            gst_event_parse_protection(event.get(), &eventKeySystemId, &data, nullptr);
    405405
    406             GstMapInfo mapInfo;
    407             if (!gst_buffer_map(data, &mapInfo, GST_MAP_READ)) {
     406            GstMappedBuffer dataMapped(data, GST_MAP_READ);
     407            if (!dataMapped) {
    408408                GST_WARNING("cannot map %s protection data", eventKeySystemId);
    409409                break;
    410410            }
    411             GST_TRACE("appending init data for %s of size %" G_GSIZE_FORMAT, eventKeySystemId, mapInfo.size);
    412             GST_MEMDUMP("init data", reinterpret_cast<const unsigned char*>(mapInfo.data), mapInfo.size);
    413             concatenatedInitDataChunks.append(mapInfo.data, mapInfo.size);
     411            GST_TRACE("appending init data for %s of size %" G_GSIZE_FORMAT, eventKeySystemId, dataMapped.size());
     412            GST_MEMDUMP("init data", reinterpret_cast<const unsigned char*>(dataMapped.data()), dataMapped.size());
     413            concatenatedInitDataChunks.append(dataMapped.data(), dataMapped.size());
    414414            ++concatenatedInitDataChunksNumber;
    415415            eventKeySystemIdString = eventKeySystemId;
     
    418418                m_handledProtectionEvents.add(GST_EVENT_SEQNUM(event.get()));
    419419            }
    420             gst_buffer_unmap(data, &mapInfo);
    421420        }
    422421
     
    12311230    }
    12321231
    1233     GstMapInfo mapInfo;
    1234     if (!gst_buffer_map(data, &mapInfo, GST_MAP_READ)) {
     1232    GstMappedBuffer dataMapped(data, GST_MAP_READ);
     1233    if (!dataMapped) {
    12351234        GST_WARNING("cannot map %s protection data", eventKeySystemUUID);
    12361235        return;
    12371236    }
    12381237
    1239     GST_TRACE("init data encountered for %s of size %" G_GSIZE_FORMAT, eventKeySystemUUID, mapInfo.size);
    1240     GST_MEMDUMP("init data", reinterpret_cast<const uint8_t*>(mapInfo.data), mapInfo.size);
    1241     InitData initData(reinterpret_cast<const uint8_t*>(mapInfo.data), mapInfo.size);
    1242     gst_buffer_unmap(data, &mapInfo);
     1238    GST_TRACE("init data encountered for %s of size %" G_GSIZE_FORMAT, eventKeySystemUUID, dataMapped.size());
     1239    GST_MEMDUMP("init data", reinterpret_cast<const uint8_t*>(dataMapped.data()), dataMapped.size());
     1240    InitData initData(reinterpret_cast<const uint8_t*>(dataMapped.data()), dataMapped.size());
    12431241
    12441242    String eventKeySystemUUIDString = eventKeySystemUUID;
  • trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitClearKeyDecryptorGStreamer.cpp

    r231565 r233796  
    2525#if ENABLE(ENCRYPTED_MEDIA) && USE(GSTREAMER)
    2626
     27#include "GStreamerCommon.h"
    2728#include "GStreamerEMEUtilities.h"
    2829#include <gcrypt.h>
     
    159160
    160161    GRefPtr<GstBuffer> keyBuffer;
    161     {
    162         GstMapInfo keyIDBufferMap;
    163         if (!gst_buffer_map(keyIDBuffer, &keyIDBufferMap, GST_MAP_READ)) {
    164             GST_ERROR_OBJECT(self, "Failed to map key ID buffer");
    165             return false;
     162    WebCore::GstMappedBuffer mappedKeyIdBuffer(keyIDBuffer, GST_MAP_READ);
     163    if (!mappedKeyIdBuffer) {
     164        GST_ERROR_OBJECT(self, "Failed to map key ID buffer");
     165        return false;
     166    }
     167
     168    for (auto& key : priv->keys) {
     169        if (!gst_buffer_memcmp(key.keyID.get(), 0, mappedKeyIdBuffer.data(), mappedKeyIdBuffer.size())) {
     170            keyBuffer = key.keyValue;
     171            break;
    166172        }
    167 
    168         for (auto& key : priv->keys) {
    169             if (!gst_buffer_memcmp(key.keyID.get(), 0, keyIDBufferMap.data, keyIDBufferMap.size)) {
    170                 keyBuffer = key.keyValue;
    171                 break;
    172             }
    173         }
    174 
    175         gst_buffer_unmap(keyIDBuffer, &keyIDBufferMap);
    176173    }
    177174
     
    187184    }
    188185
    189     GstMapInfo keyMap;
    190     if (!gst_buffer_map(keyBuffer.get(), &keyMap, GST_MAP_READ)) {
     186    WebCore::GstMappedBuffer mappedKeyBuffer(keyBuffer.get(), GST_MAP_READ);
     187    if (!mappedKeyBuffer) {
    191188        GST_ERROR_OBJECT(self, "Failed to map decryption key");
    192189        return false;
    193190    }
    194191
    195     ASSERT(keyMap.size == CLEARKEY_SIZE);
    196     error = gcry_cipher_setkey(priv->handle, keyMap.data, keyMap.size);
    197     gst_buffer_unmap(keyBuffer.get(), &keyMap);
     192    ASSERT(mappedKeyBuffer.size() == CLEARKEY_SIZE);
     193    error = gcry_cipher_setkey(priv->handle, mappedKeyBuffer.data(), mappedKeyBuffer.size());
    198194    if (error) {
    199195        GST_ERROR_OBJECT(self, "gcry_cipher_setkey failed: %s", gpg_strerror(error));
     
    206202static gboolean webKitMediaClearKeyDecryptorDecrypt(WebKitMediaCommonEncryptionDecrypt* self, GstBuffer* ivBuffer, GstBuffer* buffer, unsigned subSampleCount, GstBuffer* subSamplesBuffer)
    207203{
    208     GstMapInfo ivMap;
    209204    // Check ivBuffer isn't null.
    210205    if (!ivBuffer) {
     
    213208    }
    214209
    215     if (!gst_buffer_map(ivBuffer, &ivMap, GST_MAP_READ)) {
     210    WebCore::GstMappedBuffer mappedIVBuffer(ivBuffer, GST_MAP_READ);
     211    if (!mappedIVBuffer) {
    216212        GST_ERROR_OBJECT(self, "Failed to map IV");
    217213        return false;
     
    219215
    220216    uint8_t ctr[CLEARKEY_SIZE];
    221     if (ivMap.size == 8) {
     217    if (mappedIVBuffer.size() == 8) {
    222218        memset(ctr + 8, 0, 8);
    223         memcpy(ctr, ivMap.data, 8);
     219        memcpy(ctr, mappedIVBuffer.data(), 8);
    224220    } else {
    225         ASSERT(ivMap.size == CLEARKEY_SIZE);
    226         memcpy(ctr, ivMap.data, CLEARKEY_SIZE);
    227     }
    228     gst_buffer_unmap(ivBuffer, &ivMap);
     221        ASSERT(mappedIVBuffer.size() == CLEARKEY_SIZE);
     222        memcpy(ctr, mappedIVBuffer.data(), CLEARKEY_SIZE);
     223    }
    229224
    230225    WebKitMediaClearKeyDecryptPrivate* priv = WEBKIT_MEDIA_CK_DECRYPT_GET_PRIVATE(WEBKIT_MEDIA_CK_DECRYPT(self));
     
    241236    }
    242237
    243     GstMapInfo map;
    244     gboolean bufferMapped = gst_buffer_map(buffer, &map, static_cast<GstMapFlags>(GST_MAP_READWRITE));
    245     if (!bufferMapped) {
     238    WebCore::GstMappedBuffer mappedBuffer(buffer, GST_MAP_READWRITE);
     239    if (!mappedBuffer) {
    246240        GST_ERROR_OBJECT(self, "Failed to map buffer");
    247241        return false;
    248242    }
    249243
    250     bool returnValue = true;
    251244    GstByteReader* reader;
    252245    unsigned position = 0;
    253246    unsigned sampleIndex = 0;
    254     GstMapInfo subSamplesMap;
    255247
    256248    if (!subSampleCount) {
    257249        // Full sample encryption.
    258         GST_TRACE_OBJECT(self, "full sample encryption: %zu encrypted bytes", map.size);
     250        GST_TRACE_OBJECT(self, "full sample encryption: %zu encrypted bytes", mappedBuffer.size());
    259251
    260252        // Check if the buffer is empty.
    261         if (map.size) {
    262             cipherError = gcry_cipher_decrypt(priv->handle, map.data, map.size, 0, 0);
     253        if (mappedBuffer.size()) {
     254            cipherError = gcry_cipher_decrypt(priv->handle, mappedBuffer.data(), mappedBuffer.size(), 0, 0);
    263255            if (cipherError) {
    264256                GST_ERROR_OBJECT(self, "full sample decryption failed: %s", gpg_strerror(cipherError));
    265                 returnValue = false;
     257                return false;
    266258            }
    267259        }
    268         goto releaseBuffer;
     260        return true;
    269261    }
    270262
     
    272264    if (!subSamplesBuffer) {
    273265        GST_ERROR_OBJECT(self, "Error, the subSampleBuffer is null");
    274         returnValue = false;
    275         goto releaseBuffer;
     266        return false;
    276267    }
    277268
    278269    // Subsample encryption.
    279     if (!gst_buffer_map(subSamplesBuffer, &subSamplesMap, GST_MAP_READ)) {
     270    WebCore::GstMappedBuffer mappedSubSamplesBuffer(subSamplesBuffer, GST_MAP_READ);
     271    if (!mappedSubSamplesBuffer) {
    280272        GST_ERROR_OBJECT(self, "Failed to map subsample buffer");
    281         returnValue = false;
    282         goto releaseBuffer;
    283     }
    284 
    285     reader = gst_byte_reader_new(subSamplesMap.data, subSamplesMap.size);
    286     GST_DEBUG_OBJECT(self, "position: %d, size: %zu", position, map.size);
    287 
    288     while (position < map.size) {
     273        return false;
     274    }
     275
     276    reader = gst_byte_reader_new(mappedSubSamplesBuffer.data(), mappedSubSamplesBuffer.size());
     277    GST_DEBUG_OBJECT(self, "position: %d, size: %zu", position, mappedBuffer.size());
     278
     279    while (position < mappedBuffer.size()) {
    289280        guint16 nBytesClear = 0;
    290281        guint32 nBytesEncrypted = 0;
     
    294285                || !gst_byte_reader_get_uint32_be(reader, &nBytesEncrypted)) {
    295286                GST_DEBUG_OBJECT(self, "unsupported");
    296                 returnValue = false;
    297                 goto releaseSubsamples;
     287                gst_byte_reader_free(reader);
     288                return false;
    298289            }
    299290            sampleIndex++;
    300291        } else {
    301292            nBytesClear = 0;
    302             nBytesEncrypted = map.size - position;
     293            nBytesEncrypted = mappedBuffer.size() - position;
    303294        }
    304295
    305         GST_TRACE_OBJECT(self, "subsample index %u - %hu bytes clear (todo=%zu)", sampleIndex, nBytesClear, map.size - position);
     296        GST_TRACE_OBJECT(self, "subsample index %u - %hu bytes clear (todo=%zu)", sampleIndex, nBytesClear, mappedBuffer.size() - position);
    306297        position += nBytesClear;
    307298        if (nBytesEncrypted) {
    308             GST_TRACE_OBJECT(self, "subsample index %u - %hu bytes encrypted (todo=%zu)", sampleIndex, nBytesEncrypted, map.size - position);
    309             cipherError = gcry_cipher_decrypt(priv->handle, map.data + position, nBytesEncrypted, 0, 0);
     299            GST_TRACE_OBJECT(self, "subsample index %u - %hu bytes encrypted (todo=%zu)", sampleIndex, nBytesEncrypted, mappedBuffer.size() - position);
     300            cipherError = gcry_cipher_decrypt(priv->handle, mappedBuffer.data() + position, nBytesEncrypted, 0, 0);
    310301            if (cipherError) {
    311302                GST_ERROR_OBJECT(self, "sub sample index %u decryption failed: %s", sampleIndex, gpg_strerror(cipherError));
    312                 returnValue = false;
    313                 goto releaseSubsamples;
     303                gst_byte_reader_free(reader);
     304                return false;
    314305            }
    315306            position += nBytesEncrypted;
    316307        }
    317308    }
    318 releaseSubsamples:
     309
    319310    gst_byte_reader_free(reader);
    320     gst_buffer_unmap(subSamplesBuffer, &subSamplesMap);
    321 
    322 releaseBuffer:
    323     gst_buffer_unmap(buffer, &map);
    324     return returnValue;
     311    return true;
    325312}
    326313
Note: See TracChangeset for help on using the changeset viewer.