Diff
Modified: trunk/Source/WebCore/ChangeLog (237920 => 237921)
--- trunk/Source/WebCore/ChangeLog 2018-11-07 11:29:27 UTC (rev 237920)
+++ trunk/Source/WebCore/ChangeLog 2018-11-07 11:50:30 UTC (rev 237921)
@@ -1,3 +1,49 @@
+2018-11-07 Charlie Turner <ctur...@igalia.com>
+
+ [EME][GStreamer] Ensure key id buffers are present and simplify lifetime management of ClearKey class.
+ https://bugs.webkit.org/show_bug.cgi?id=191157
+
+ Reviewed by Xabier Rodriguez-Calvar.
+
+ This is in preparation for moving the clearkey decryptor behind a
+ new decrypt API in CDMInstance, which will be sent into the
+ pipeline to handle key management and decryption. This is for a
+ later patch.
+
+ Covered by existing clear key tests in media/encrypted-media.
+
+ * platform/graphics/gstreamer/GStreamerCommon.h:
+ (WebCore::GstMappedBuffer::data const): Add a const data accessor,
+ since we are now providing operator=='s on const objects of this
+ class that need const access to the data pointer.
+ (WebCore::GstMappedBuffer::operator==): Add a swap of the new
+ equality operator so you don't have to remember to have the
+ GstBuffer on the RHS of the equality all the time.
+ (WebCore::operator==): Define an equality operator between Gst
+ buffers and WebCore's mapped buffers. Gst creates a ref and a
+ separate read view under the covers in the memcmp call, so we do
+ not need to map the buffer ourselves.
+ * platform/graphics/gstreamer/eme/WebKitClearKeyDecryptorGStreamer.cpp:
+ (webkit_media_clear_key_decrypt_class_init): Remove setup/release
+ bindings.
+ (webkit_media_clear_key_decrypt_init): Initialize gcrypt cipher
+ here once instead of for every buffer to be decrypted.
+ (webKitMediaClearKeyDecryptorFinalize): And destroy the cipher
+ context when the decryptor is destroyed.
+ (webKitMediaClearKeyDecryptorFindAndSetKey): Factor out the key
+ retrieval and context setting in this method, call it for each
+ sample.
+ (webKitMediaClearKeyDecryptorDecrypt): Base key id buffer into
+ this function, and remove cipher creation / destroy methods.
+ * platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.cpp:
+ (webkit_media_common_encryption_decrypt_class_init): Remove
+ setup/release bindings.
+ (webkitMediaCommonEncryptionDecryptTransformInPlace): Ensure a key
+ id is present and pass it to the decrypt class method.
+ (webKitMediaCommonEncryptionDecryptDefaultSetupCipher): Deleted.
+ (webKitMediaCommonEncryptionDecryptDefaultReleaseCipher): Deleted.
+ * platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.h:
+
2018-11-07 Frederic Wang <fw...@igalia.com>
[Cairo] Move state change operations from GraphicsContextCairo to CairoOperations
Modified: trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h (237920 => 237921)
--- trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h 2018-11-07 11:29:27 UTC (rev 237920)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h 2018-11-07 11:50:30 UTC (rev 237921)
@@ -108,15 +108,33 @@
}
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); }
+
size_t size() const { ASSERT(m_isValid); return static_cast<size_t>(m_info.size); }
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); }
+
GstBuffer* m_buffer { nullptr };
GstMapInfo m_info;
bool m_isValid { false };
};
+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());
+}
+
+inline bool operator==(const GstMappedBuffer& a, const GstBuffer* b)
+{
+ GstBuffer* nonConstB = const_cast<GstBuffer*>(b);
+ return a.size() == gst_buffer_get_size(nonConstB) && !gst_buffer_memcmp(nonConstB, 0, a.data(), a.size());
+}
+
bool gstRegistryHasElementForMediaType(GList* elementFactories, const char* capsString);
void connectSimpleBusMessageCallback(GstElement *pipeline);
void disconnectSimpleBusMessageCallback(GstElement *pipeline);
Modified: trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitClearKeyDecryptorGStreamer.cpp (237920 => 237921)
--- trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitClearKeyDecryptorGStreamer.cpp 2018-11-07 11:29:27 UTC (rev 237920)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitClearKeyDecryptorGStreamer.cpp 2018-11-07 11:50:30 UTC (rev 237921)
@@ -45,9 +45,7 @@
static void webKitMediaClearKeyDecryptorFinalize(GObject*);
static gboolean webKitMediaClearKeyDecryptorHandleKeyResponse(WebKitMediaCommonEncryptionDecrypt* self, GstEvent*);
-static gboolean webKitMediaClearKeyDecryptorSetupCipher(WebKitMediaCommonEncryptionDecrypt*, GstBuffer*);
-static gboolean webKitMediaClearKeyDecryptorDecrypt(WebKitMediaCommonEncryptionDecrypt*, GstBuffer* iv, GstBuffer* sample, unsigned subSamplesCount, GstBuffer* subSamples);
-static void webKitMediaClearKeyDecryptorReleaseCipher(WebKitMediaCommonEncryptionDecrypt*);
+static gboolean webKitMediaClearKeyDecryptorDecrypt(WebKitMediaCommonEncryptionDecrypt*, GstBuffer* iv, GstBuffer* keyid, GstBuffer* sample, unsigned subSamplesCount, GstBuffer* subSamples);
GST_DEBUG_CATEGORY_STATIC(webkit_media_clear_key_decrypt_debug_category);
#define GST_CAT_DEFAULT webkit_media_clear_key_decrypt_debug_category
@@ -89,9 +87,7 @@
WebKitMediaCommonEncryptionDecryptClass* cencClass = WEBKIT_MEDIA_CENC_DECRYPT_CLASS(klass);
cencClass->protectionSystemId = WebCore::GStreamerEMEUtilities::s_ClearKeyUUID;
cencClass->handleKeyResponse = GST_DEBUG_FUNCPTR(webKitMediaClearKeyDecryptorHandleKeyResponse);
- cencClass->setupCipher = GST_DEBUG_FUNCPTR(webKitMediaClearKeyDecryptorSetupCipher);
cencClass->decrypt = GST_DEBUG_FUNCPTR(webKitMediaClearKeyDecryptorDecrypt);
- cencClass->releaseCipher = GST_DEBUG_FUNCPTR(webKitMediaClearKeyDecryptorReleaseCipher);
g_type_class_add_private(klass, sizeof(WebKitMediaClearKeyDecryptPrivate));
}
@@ -102,6 +98,10 @@
self->priv = priv;
new (priv) WebKitMediaClearKeyDecryptPrivate();
+ if (gcry_error_t error = gcry_cipher_open(&(priv->handle), GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CTR, GCRY_CIPHER_SECURE)) {
+ GST_ERROR_OBJECT(self, "Failed to create AES 128 CTR cipher handle: %s", gpg_strerror(error));
+ ASSERT(!error);
+ }
}
static void webKitMediaClearKeyDecryptorFinalize(GObject* object)
@@ -108,7 +108,7 @@
{
WebKitMediaClearKeyDecrypt* self = WEBKIT_MEDIA_CK_DECRYPT(object);
WebKitMediaClearKeyDecryptPrivate* priv = self->priv;
-
+ gcry_cipher_close(priv->handle);
priv->~WebKitMediaClearKeyDecryptPrivate();
GST_CALL_PARENT(G_OBJECT_CLASS, finalize, (object));
@@ -150,25 +150,11 @@
return TRUE;
}
-static gboolean webKitMediaClearKeyDecryptorSetupCipher(WebKitMediaCommonEncryptionDecrypt* self, GstBuffer* keyIDBuffer)
+static gboolean webKitMediaClearKeyDecryptorFindAndSetKey(WebKitMediaClearKeyDecryptPrivate* priv, const WebCore::GstMappedBuffer& keyIDBuffer)
{
- if (!keyIDBuffer) {
- GST_ERROR_OBJECT(self, "got no key id buffer");
- return false;
- }
-
- WebKitMediaClearKeyDecryptPrivate* priv = WEBKIT_MEDIA_CK_DECRYPT_GET_PRIVATE(WEBKIT_MEDIA_CK_DECRYPT(self));
- gcry_error_t error;
-
GRefPtr<GstBuffer> keyBuffer;
- 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, mappedKeyIdBuffer.data(), mappedKeyIdBuffer.size())) {
+ if (key.keyID.get() == keyIDBuffer) {
keyBuffer = key.keyValue;
break;
}
@@ -175,33 +161,26 @@
}
if (!keyBuffer) {
- GST_ERROR_OBJECT(self, "Failed to find an appropriate key buffer");
+ GST_ERROR_OBJECT(priv, "Failed to find an appropriate key buffer");
return false;
}
- error = gcry_cipher_open(&(priv->handle), GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CTR, GCRY_CIPHER_SECURE);
- if (error) {
- GST_ERROR_OBJECT(self, "Failed to create AES 128 CTR cipher handle: %s", gpg_strerror(error));
+ WebCore::GstMappedBuffer mappedKeyValueBuffer(keyBuffer.get(), GST_MAP_READ);
+ if (!mappedKeyValueBuffer) {
+ GST_ERROR_OBJECT(priv, "Failed to map decryption key");
return false;
}
- WebCore::GstMappedBuffer mappedKeyBuffer(keyBuffer.get(), GST_MAP_READ);
- if (!mappedKeyBuffer) {
- GST_ERROR_OBJECT(self, "Failed to map decryption key");
+ 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;
}
- 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;
- }
-
return true;
}
-static gboolean webKitMediaClearKeyDecryptorDecrypt(WebKitMediaCommonEncryptionDecrypt* self, GstBuffer* ivBuffer, GstBuffer* buffer, unsigned subSampleCount, GstBuffer* subSamplesBuffer)
+static gboolean webKitMediaClearKeyDecryptorDecrypt(WebKitMediaCommonEncryptionDecrypt* self, GstBuffer* ivBuffer, GstBuffer* keyIDBuffer, GstBuffer* buffer, unsigned subSampleCount, GstBuffer* subSamplesBuffer)
{
// Check ivBuffer isn't null.
if (!ivBuffer) {
@@ -233,10 +212,16 @@
// Check buffer isn't null.
if (!buffer) {
- GST_ERROR_OBJECT(self, "Error, the buffer is null");
+ GST_ERROR_OBJECT(self, "No buffer to decrypt");
return false;
}
+ WebCore::GstMappedBuffer mappedKeyIdBuffer(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);
if (!mappedBuffer) {
GST_ERROR_OBJECT(self, "Failed to map buffer");
@@ -243,6 +228,8 @@
return false;
}
+ webKitMediaClearKeyDecryptorFindAndSetKey(priv, mappedKeyIdBuffer);
+
unsigned position = 0;
unsigned sampleIndex = 0;
@@ -309,10 +296,4 @@
return true;
}
-static void webKitMediaClearKeyDecryptorReleaseCipher(WebKitMediaCommonEncryptionDecrypt* self)
-{
- WebKitMediaClearKeyDecryptPrivate* priv = WEBKIT_MEDIA_CK_DECRYPT_GET_PRIVATE(WEBKIT_MEDIA_CK_DECRYPT(self));
- gcry_cipher_close(priv->handle);
-}
-
#endif // ENABLE(ENCRYPTED_MEDIA) && USE(GSTREAMER)
Modified: trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.cpp (237920 => 237921)
--- trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.cpp 2018-11-07 11:29:27 UTC (rev 237920)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.cpp 2018-11-07 11:50:30 UTC (rev 237921)
@@ -45,8 +45,6 @@
static GstFlowReturn webkitMediaCommonEncryptionDecryptTransformInPlace(GstBaseTransform*, GstBuffer*);
static gboolean webkitMediaCommonEncryptionDecryptSinkEventHandler(GstBaseTransform*, GstEvent*);
-static gboolean webKitMediaCommonEncryptionDecryptDefaultSetupCipher(WebKitMediaCommonEncryptionDecrypt*, GstBuffer*);
-static void webKitMediaCommonEncryptionDecryptDefaultReleaseCipher(WebKitMediaCommonEncryptionDecrypt*);
GST_DEBUG_CATEGORY_STATIC(webkit_media_common_encryption_decrypt_debug_category);
#define GST_CAT_DEFAULT webkit_media_common_encryption_decrypt_debug_category
@@ -71,9 +69,6 @@
baseTransformClass->transform_ip_on_passthrough = FALSE;
baseTransformClass->sink_event = GST_DEBUG_FUNCPTR(webkitMediaCommonEncryptionDecryptSinkEventHandler);
- klass->setupCipher = GST_DEBUG_FUNCPTR(webKitMediaCommonEncryptionDecryptDefaultSetupCipher);
- klass->releaseCipher = GST_DEBUG_FUNCPTR(webKitMediaCommonEncryptionDecryptDefaultReleaseCipher);
-
g_type_class_add_private(klass, sizeof(WebKitMediaCommonEncryptionDecryptPrivate));
}
@@ -269,35 +264,31 @@
}
value = gst_structure_get_value(protectionMeta->info, "kid");
- GstBuffer* keyIDBuffer = nullptr;
- if (value)
- keyIDBuffer = gst_value_get_buffer(value);
- WebKitMediaCommonEncryptionDecryptClass* klass = WEBKIT_MEDIA_CENC_DECRYPT_GET_CLASS(self);
- if (!klass->setupCipher(self, keyIDBuffer)) {
- GST_ERROR_OBJECT(self, "Failed to configure cipher");
+ if (!value) {
+ GST_ERROR_OBJECT(self, "Failed to get key id for buffer");
gst_buffer_remove_meta(buffer, reinterpret_cast<GstMeta*>(protectionMeta));
return GST_FLOW_NOT_SUPPORTED;
}
+ GstBuffer* keyIDBuffer = gst_value_get_buffer(value);
value = gst_structure_get_value(protectionMeta->info, "iv");
if (!value) {
GST_ERROR_OBJECT(self, "Failed to get IV for sample");
- klass->releaseCipher(self);
gst_buffer_remove_meta(buffer, reinterpret_cast<GstMeta*>(protectionMeta));
return GST_FLOW_NOT_SUPPORTED;
}
GstBuffer* ivBuffer = gst_value_get_buffer(value);
+ WebKitMediaCommonEncryptionDecryptClass* klass = WEBKIT_MEDIA_CENC_DECRYPT_GET_CLASS(self);
+
GST_TRACE_OBJECT(self, "decrypting");
- if (!klass->decrypt(self, ivBuffer, buffer, subSampleCount, subSamplesBuffer)) {
+ if (!klass->decrypt(self, ivBuffer, keyIDBuffer, buffer, subSampleCount, subSamplesBuffer)) {
GST_ERROR_OBJECT(self, "Decryption failed");
- klass->releaseCipher(self);
gst_buffer_remove_meta(buffer, reinterpret_cast<GstMeta*>(protectionMeta));
return GST_FLOW_NOT_SUPPORTED;
}
- klass->releaseCipher(self);
gst_buffer_remove_meta(buffer, reinterpret_cast<GstMeta*>(protectionMeta));
return GST_FLOW_OK;
}
@@ -356,15 +347,4 @@
return result;
}
-
-static gboolean webKitMediaCommonEncryptionDecryptDefaultSetupCipher(WebKitMediaCommonEncryptionDecrypt*, GstBuffer*)
-{
- return true;
-}
-
-
-static void webKitMediaCommonEncryptionDecryptDefaultReleaseCipher(WebKitMediaCommonEncryptionDecrypt*)
-{
-}
-
#endif // ENABLE(ENCRYPTED_MEDIA) && USE(GSTREAMER)
Modified: trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.h (237920 => 237921)
--- trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.h 2018-11-07 11:29:27 UTC (rev 237920)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.h 2018-11-07 11:50:30 UTC (rev 237921)
@@ -54,9 +54,7 @@
const char* protectionSystemId;
gboolean (*handleKeyResponse)(WebKitMediaCommonEncryptionDecrypt*, GstEvent* event);
- gboolean (*setupCipher)(WebKitMediaCommonEncryptionDecrypt*, GstBuffer*);
- gboolean (*decrypt)(WebKitMediaCommonEncryptionDecrypt*, GstBuffer* ivBuffer, GstBuffer* buffer, unsigned subSamplesCount, GstBuffer* subSamplesBuffer);
- void (*releaseCipher)(WebKitMediaCommonEncryptionDecrypt*);
+ gboolean (*decrypt)(WebKitMediaCommonEncryptionDecrypt*, GstBuffer* ivBuffer, GstBuffer* keyIDBuffer, GstBuffer* buffer, unsigned subSamplesCount, GstBuffer* subSamplesBuffer);
};
G_END_DECLS