Changeset 219946 in webkit
- Timestamp:
- Jul 26, 2017, 7:33:10 AM (9 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 4 edited
-
ChangeLog (modified) (1 diff)
-
platform/graphics/gstreamer/eme/WebKitClearKeyDecryptorGStreamer.cpp (modified) (5 diffs)
-
platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.cpp (modified) (3 diffs)
-
platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r219945 r219946 1 2017-07-26 Zan Dobersek <zdobersek@igalia.com> 2 3 [EME][GStreamer] Multi-key support in the GStreamer ClearKey decryptor 4 https://bugs.webkit.org/show_bug.cgi?id=174779 5 6 Reviewed by Xabier Rodriguez-Calvar. 7 8 In the CENC decryptor, the key ID value is retrieved from the info structure 9 on the GstProtectionMeta object. GstBuffer for that value is retrieved and 10 passed to the setupCipher() function. 11 12 In the ClearKey decryptor (which extends the CENC decryptor), the single 13 GstBuffer object on the private instance that holds the key value is replaced 14 with a Vector object that holds pairs of key ID and value GstBuffers. In the 15 handleKeyResponse() implementation that Vector is emptied and then refilled 16 with key ID and value pairs that are passed in through the drm-cipher-clearkey 17 structure that's attached to the GstEvent that signalled new key information. 18 19 In the ClearKey decryptor's setupCipher() implementation the passed-in key ID 20 buffer is used to find a matching key ID and value pair stored on the private 21 instance. If not found, an error is thrown. If found, the matching key value 22 is used for decryption. 23 24 * platform/graphics/gstreamer/eme/WebKitClearKeyDecryptorGStreamer.cpp: 25 (webKitMediaClearKeyDecryptorHandleKeyResponse): 26 (webKitMediaClearKeyDecryptorSetupCipher): 27 * platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.cpp: 28 (webkitMediaCommonEncryptionDecryptTransformInPlace): 29 (webKitMediaCommonEncryptionDecryptDefaultSetupCipher): 30 * platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.h: 31 1 32 2017-07-26 Zan Dobersek <zdobersek@igalia.com> 2 33 -
trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitClearKeyDecryptorGStreamer.cpp
r217966 r219946 32 32 #define CLEARKEY_SIZE 16 33 33 34 struct Key { 35 GRefPtr<GstBuffer> keyID; 36 GRefPtr<GstBuffer> keyValue; 37 }; 38 34 39 #define WEBKIT_MEDIA_CK_DECRYPT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), WEBKIT_TYPE_MEDIA_CK_DECRYPT, WebKitMediaClearKeyDecryptPrivate)) 35 40 struct _WebKitMediaClearKeyDecryptPrivate { 36 GRefPtr<GstBuffer> key;41 Vector<Key> keys; 37 42 gcry_cipher_hd_t handle; 38 43 }; … … 40 45 static void webKitMediaClearKeyDecryptorFinalize(GObject*); 41 46 static gboolean webKitMediaClearKeyDecryptorHandleKeyResponse(WebKitMediaCommonEncryptionDecrypt* self, GstEvent*); 42 static gboolean webKitMediaClearKeyDecryptorSetupCipher(WebKitMediaCommonEncryptionDecrypt* );47 static gboolean webKitMediaClearKeyDecryptorSetupCipher(WebKitMediaCommonEncryptionDecrypt*, GstBuffer*); 43 48 static gboolean webKitMediaClearKeyDecryptorDecrypt(WebKitMediaCommonEncryptionDecrypt*, GstBuffer* iv, GstBuffer* sample, unsigned subSamplesCount, GstBuffer* subSamples); 44 49 static void webKitMediaClearKeyDecryptorReleaseCipher(WebKitMediaCommonEncryptionDecrypt*); … … 121 126 const GstStructure* structure = gst_event_get_structure(event); 122 127 123 if (!gst_structure_has_name(structure, "drm-cipher")) 128 // Demand the `drm-cipher-clearkey` GstStructure. 129 if (!gst_structure_has_name(structure, "drm-cipher-clearkey")) 124 130 return FALSE; 125 131 126 const GValue* value = gst_structure_get_value(structure, "key"); 127 priv->key.clear(); 128 priv->key = adoptGRef(gst_buffer_copy(gst_value_get_buffer(value))); 132 // Retrieve the `key-ids` GStreamer value list. 133 const GValue* keyIDsList = gst_structure_get_value(structure, "key-ids"); 134 ASSERT(keyIDsList && GST_VALUE_HOLDS_LIST(keyIDsList)); 135 unsigned keyIDsListSize = gst_value_list_get_size(keyIDsList); 136 137 // Retrieve the `key-values` GStreamer value list. 138 const GValue* keyValuesList = gst_structure_get_value(structure, "key-values"); 139 ASSERT(keyValuesList && GST_VALUE_HOLDS_LIST(keyValuesList)); 140 unsigned keyValuesListSize = gst_value_list_get_size(keyValuesList); 141 142 // Bail if somehow the two lists don't match in size. 143 if (keyIDsListSize != keyValuesListSize) 144 return FALSE; 145 146 // Clear out the previous list of keys. 147 priv->keys.clear(); 148 149 // Append the retrieved GstBuffer objects containing each key's ID and value to the list of Key objects. 150 for (unsigned i = 0; i < keyIDsListSize; ++i) { 151 GRefPtr<GstBuffer> keyIDBuffer(gst_value_get_buffer(gst_value_list_get_value(keyIDsList, i))); 152 GRefPtr<GstBuffer> keyValueBuffer(gst_value_get_buffer(gst_value_list_get_value(keyValuesList, i))); 153 priv->keys.append(Key { WTFMove(keyIDBuffer), WTFMove(keyValueBuffer) }); 154 } 155 129 156 return TRUE; 130 157 } 131 158 132 static gboolean webKitMediaClearKeyDecryptorSetupCipher(WebKitMediaCommonEncryptionDecrypt* self )159 static gboolean webKitMediaClearKeyDecryptorSetupCipher(WebKitMediaCommonEncryptionDecrypt* self, GstBuffer* keyIDBuffer) 133 160 { 134 161 WebKitMediaClearKeyDecryptPrivate* priv = WEBKIT_MEDIA_CK_DECRYPT_GET_PRIVATE(WEBKIT_MEDIA_CK_DECRYPT(self)); 135 162 gcry_error_t error; 136 163 137 ASSERT(priv->key); 138 if (!priv->key) { 139 GST_ERROR_OBJECT(self, "Decryption key not provided"); 164 GRefPtr<GstBuffer> keyBuffer; 165 { 166 GstMapInfo keyIDBufferMap; 167 if (!gst_buffer_map(keyIDBuffer, &keyIDBufferMap, GST_MAP_READ)) { 168 GST_ERROR_OBJECT(self, "Failed to map key ID buffer"); 169 return false; 170 } 171 172 for (auto& key : priv->keys) { 173 if (!gst_buffer_memcmp(key.keyID.get(), 0, keyIDBufferMap.data, keyIDBufferMap.size)) { 174 keyBuffer = key.keyValue; 175 break; 176 } 177 } 178 179 gst_buffer_unmap(keyIDBuffer, &keyIDBufferMap); 180 } 181 182 if (!keyBuffer) { 183 GST_ERROR_OBJECT(self, "Failed to find an appropriate key buffer"); 140 184 return false; 141 185 } … … 148 192 149 193 GstMapInfo keyMap; 150 if (!gst_buffer_map( priv->key.get(), &keyMap, GST_MAP_READ)) {194 if (!gst_buffer_map(keyBuffer.get(), &keyMap, GST_MAP_READ)) { 151 195 GST_ERROR_OBJECT(self, "Failed to map decryption key"); 152 196 return false; … … 155 199 ASSERT(keyMap.size == CLEARKEY_SIZE); 156 200 error = gcry_cipher_setkey(priv->handle, keyMap.data, keyMap.size); 157 gst_buffer_unmap( priv->key.get(), &keyMap);201 gst_buffer_unmap(keyBuffer.get(), &keyMap); 158 202 if (error) { 159 203 GST_ERROR_OBJECT(self, "gcry_cipher_setkey failed: %s", gpg_strerror(error)); -
trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.cpp
r217966 r219946 45 45 static gboolean webkitMediaCommonEncryptionDecryptSinkEventHandler(GstBaseTransform*, GstEvent*); 46 46 47 static gboolean webKitMediaCommonEncryptionDecryptDefaultSetupCipher(WebKitMediaCommonEncryptionDecrypt* );47 static gboolean webKitMediaCommonEncryptionDecryptDefaultSetupCipher(WebKitMediaCommonEncryptionDecrypt*, GstBuffer*); 48 48 static void webKitMediaCommonEncryptionDecryptDefaultReleaseCipher(WebKitMediaCommonEncryptionDecrypt*); 49 49 … … 254 254 } 255 255 256 value = gst_structure_get_value(protectionMeta->info, "kid"); 257 if (!value) { 258 GST_ERROR_OBJECT(self, "Failed to get key ID for sample"); 259 gst_buffer_remove_meta(buffer, reinterpret_cast<GstMeta*>(protectionMeta)); 260 return GST_FLOW_NOT_SUPPORTED; 261 } 262 263 GstBuffer* keyIDBuffer = gst_value_get_buffer(value); 256 264 WebKitMediaCommonEncryptionDecryptClass* klass = WEBKIT_MEDIA_CENC_DECRYPT_GET_CLASS(self); 257 if (!klass->setupCipher(self )) {265 if (!klass->setupCipher(self, keyIDBuffer)) { 258 266 GST_ERROR_OBJECT(self, "Failed to configure cipher"); 259 267 gst_buffer_remove_meta(buffer, reinterpret_cast<GstMeta*>(protectionMeta)); … … 350 358 351 359 352 static gboolean webKitMediaCommonEncryptionDecryptDefaultSetupCipher(WebKitMediaCommonEncryptionDecrypt* )360 static gboolean webKitMediaCommonEncryptionDecryptDefaultSetupCipher(WebKitMediaCommonEncryptionDecrypt*, GstBuffer*) 353 361 { 354 362 return true; -
trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.h
r217966 r219946 55 55 const char* protectionSystemId; 56 56 gboolean (*handleKeyResponse)(WebKitMediaCommonEncryptionDecrypt*, GstEvent* event); 57 gboolean (*setupCipher)(WebKitMediaCommonEncryptionDecrypt* );57 gboolean (*setupCipher)(WebKitMediaCommonEncryptionDecrypt*, GstBuffer*); 58 58 gboolean (*decrypt)(WebKitMediaCommonEncryptionDecrypt*, GstBuffer* ivBuffer, GstBuffer* buffer, unsigned subSamplesCount, GstBuffer* subSamplesBuffer); 59 59 void (*releaseCipher)(WebKitMediaCommonEncryptionDecrypt*);
Note:
See TracChangeset
for help on using the changeset viewer.