Diff
Modified: trunk/Source/WebCore/ChangeLog (238082 => 238083)
--- trunk/Source/WebCore/ChangeLog 2018-11-12 09:05:49 UTC (rev 238082)
+++ trunk/Source/WebCore/ChangeLog 2018-11-12 12:40:12 UTC (rev 238083)
@@ -1,3 +1,46 @@
+2018-11-12 Xabier Rodriguez Calvar <calva...@igalia.com>
+
+ [GStreamer][EME] waitingforkey event should consider decryptors' waiting status
+ https://bugs.webkit.org/show_bug.cgi?id=191459
+
+ Reviewed by Carlos Garcia Campos.
+
+ The new cross platform architecture to report waitingforkey and
+ recover from it requires a more accurate knowledge of what is
+ going on with the decryptors because events are reported only once
+ (per key exchange run) and crossplatform only continues if we are
+ actually ready to continue, meaning that no decryptors are
+ waiting.
+
+ * platform/graphics/gstreamer/GUniquePtrGStreamer.h: Added
+ GstIterator deleter.
+ * platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp:
+ (WebCore::MediaPlayerPrivateGStreamerBase::setWaitingForKey): Bail
+ out if we are requested to not wait anymore but there are still
+ waiting decryptors.
+ (WebCore::MediaPlayerPrivateGStreamerBase::waitingForKey const):
+ Query the pipeline, just a query after pipeline is built and
+ manual inspection during build. The query is optimal but sometimes
+ we can get this request when the pipeline is under construction so
+ queries do not arrive at the decryptors and we have to deliver it
+ by ourselves.
+ (WebCore::MediaPlayerPrivateGStreamerBase::reportWaitingForKey:
+ * platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h:
+ (WebCore::MediaPlayerPrivateGStreamerBase::reportWaitingForKey:
+ Deleted because it is now inlined.
+ * platform/graphics/gstreamer/eme/WebKitClearKeyDecryptorGStreamer.cpp:
+ (webKitMediaClearKeyDecryptorDecrypt): Fixed small compiler warning.
+ * platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.cpp:
+ (webkit_media_common_encryption_decrypt_class_init): Override
+ query method.
+ (webkitMediaCommonEncryptionDecryptTransformInPlace): When the
+ decryptor is going to block to wait, report before. When the
+ decryptor receives the key, report it got it.
+ (webkitMediaCommonEncryptionDecryptSinkEventHandler): Do not
+ handle waitingforkey here.
+ (webkitMediaCommonEncryptionDecryptorQueryHandler): Report if the
+ decryptor is waiting.
+
2018-11-12 Michael Catanzaro <mcatanz...@igalia.com>
[GTK] Silence ATK_XY_PARENT warnings
Modified: trunk/Source/WebCore/platform/graphics/gstreamer/GUniquePtrGStreamer.h (238082 => 238083)
--- trunk/Source/WebCore/platform/graphics/gstreamer/GUniquePtrGStreamer.h 2018-11-12 09:05:49 UTC (rev 238082)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/GUniquePtrGStreamer.h 2018-11-12 12:40:12 UTC (rev 238083)
@@ -32,6 +32,7 @@
WTF_DEFINE_GPTR_DELETER(GstStructure, gst_structure_free)
WTF_DEFINE_GPTR_DELETER(GstInstallPluginsContext, gst_install_plugins_context_free)
+WTF_DEFINE_GPTR_DELETER(GstIterator, gst_iterator_free)
WTF_DEFINE_GPTR_DELETER(GstSegment, gst_segment_free)
WTF_DEFINE_GPTR_DELETER(GstFlowCombiner, gst_flow_combiner_free)
WTF_DEFINE_GPTR_DELETER(GstByteReader, gst_byte_reader_free)
Modified: trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp (238082 => 238083)
--- trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp 2018-11-12 09:05:49 UTC (rev 238082)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp 2018-11-12 12:40:12 UTC (rev 238083)
@@ -50,6 +50,7 @@
#include "CDMInstance.h"
#include "GStreamerEMEUtilities.h"
#include "SharedBuffer.h"
+#include "WebKitCommonEncryptionDecryptorGStreamer.h"
#endif
#if USE(GSTREAMER_GL)
@@ -1335,24 +1336,51 @@
initializationDataEncountered(event);
}
-void MediaPlayerPrivateGStreamerBase::reportWaitingForKey()
-{
- GST_TRACE("waiting for key");
- m_player->waitingForKeyChanged();
-}
-
void MediaPlayerPrivateGStreamerBase::setWaitingForKey(bool waitingForKey)
{
- if (waitingForKey == m_waitingForKey)
+ // We bail out if values did not change or if we are requested to not wait anymore but there are still waiting decryptors.
+ GST_TRACE("waitingForKey %s, m_waitingForKey %s", boolForPrinting(waitingForKey), boolForPrinting(m_waitingForKey));
+ if (waitingForKey == m_waitingForKey || (!waitingForKey && this->waitingForKey()))
return;
m_waitingForKey = waitingForKey;
- reportWaitingForKey();
+ GST_DEBUG("waiting for key changed %s", boolForPrinting(m_waitingForKey));
+ m_player->waitingForKeyChanged();
}
bool MediaPlayerPrivateGStreamerBase::waitingForKey() const
{
- return m_waitingForKey;
+ if (!m_pipeline)
+ return false;
+
+ GstState state;
+ gst_element_get_state(m_pipeline.get(), &state, nullptr, 0);
+
+ bool result = false;
+ GRefPtr<GstQuery> query = adoptGRef(gst_query_new_custom(GST_QUERY_CUSTOM, gst_structure_new_empty("any-decryptor-waiting-for-key")));
+ if (state >= GST_STATE_PAUSED) {
+ result = gst_element_query(m_pipeline.get(), query.get());
+ GST_TRACE("query result %s, on %s", boolForPrinting(result), gst_element_state_get_name(state));
+ } else if (state >= GST_STATE_READY) {
+ // Running a query in the pipeline is easier but it only works when the pipeline is set up and running, otherwise we need to inspect it and ask the decryptors directly.
+ GUniquePtr<GstIterator> iterator(gst_bin_iterate_recurse(GST_BIN(m_pipeline.get())));
+ GstIteratorResult iteratorResult;
+ do {
+ iteratorResult = gst_iterator_fold(iterator.get(), [](const GValue *item, GValue *, gpointer data) -> gboolean {
+ GstElement* element = GST_ELEMENT(g_value_get_object(item));
+ GstQuery* query = GST_QUERY(data);
+ return !WEBKIT_IS_MEDIA_CENC_DECRYPT(element) || !gst_element_query(element, query);
+ }, nullptr, query.get());
+ if (iteratorResult == GST_ITERATOR_RESYNC)
+ gst_iterator_resync(iterator.get());
+ } while (iteratorResult == GST_ITERATOR_RESYNC);
+ if (iteratorResult == GST_ITERATOR_ERROR)
+ GST_WARNING("iterator returned an error");
+ result = iteratorResult == GST_ITERATOR_OK;
+ GST_TRACE("iterator result %d, waiting %s", iteratorResult, boolForPrinting(result));
+ }
+
+ return result;
}
#endif
Modified: trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h (238082 => 238083)
--- trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h 2018-11-12 09:05:49 UTC (rev 238082)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h 2018-11-12 12:40:12 UTC (rev 238083)
@@ -154,8 +154,7 @@
void dispatchCDMInstance();
void initializationDataEncountered(GstEvent*);
void setWaitingForKey(bool);
- bool waitingForKey() const;
- void reportWaitingForKey();
+ bool waitingForKey() const override;
#endif
static bool supportsKeySystem(const String& keySystem, const String& mimeType);
Modified: trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitClearKeyDecryptorGStreamer.cpp (238082 => 238083)
--- trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitClearKeyDecryptorGStreamer.cpp 2018-11-12 09:05:49 UTC (rev 238082)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitClearKeyDecryptorGStreamer.cpp 2018-11-12 12:40:12 UTC (rev 238083)
@@ -283,7 +283,7 @@
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, mappedBuffer.size() - position);
+ 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));
Modified: trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.cpp (238082 => 238083)
--- trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.cpp 2018-11-12 09:05:49 UTC (rev 238082)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/eme/WebKitCommonEncryptionDecryptorGStreamer.cpp 2018-11-12 12:40:12 UTC (rev 238083)
@@ -27,6 +27,7 @@
#include "GStreamerCommon.h"
#include <wtf/Condition.h>
+#include <wtf/PrintStream.h>
#include <wtf/RunLoop.h>
#define WEBKIT_MEDIA_CENC_DECRYPT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), WEBKIT_TYPE_MEDIA_CENC_DECRYPT, WebKitMediaCommonEncryptionDecryptPrivate))
@@ -44,6 +45,7 @@
static GstCaps* webkitMediaCommonEncryptionDecryptTransformCaps(GstBaseTransform*, GstPadDirection, GstCaps*, GstCaps*);
static GstFlowReturn webkitMediaCommonEncryptionDecryptTransformInPlace(GstBaseTransform*, GstBuffer*);
static gboolean webkitMediaCommonEncryptionDecryptSinkEventHandler(GstBaseTransform*, GstEvent*);
+static gboolean webkitMediaCommonEncryptionDecryptorQueryHandler(GstBaseTransform*, GstPadDirection, GstQuery*);
GST_DEBUG_CATEGORY_STATIC(webkit_media_common_encryption_decrypt_debug_category);
@@ -68,6 +70,7 @@
baseTransformClass->transform_caps = GST_DEBUG_FUNCPTR(webkitMediaCommonEncryptionDecryptTransformCaps);
baseTransformClass->transform_ip_on_passthrough = FALSE;
baseTransformClass->sink_event = GST_DEBUG_FUNCPTR(webkitMediaCommonEncryptionDecryptSinkEventHandler);
+ baseTransformClass->query = GST_DEBUG_FUNCPTR(webkitMediaCommonEncryptionDecryptorQueryHandler);
g_type_class_add_private(klass, sizeof(WebKitMediaCommonEncryptionDecryptPrivate));
}
@@ -215,6 +218,8 @@
return GST_FLOW_NOT_SUPPORTED;
}
GST_DEBUG_OBJECT(self, "key received, continuing");
+ priv->waitingForKey = false;
+ gst_element_post_message(GST_ELEMENT(self), gst_message_new_element(GST_OBJECT(self), gst_structure_new_empty("drm-key-received")));
}
GstProtectionMeta* protectionMeta = reinterpret_cast<GstProtectionMeta*>(gst_buffer_get_protection_meta(buffer));
@@ -306,12 +311,7 @@
if (klass->handleKeyResponse(self, event)) {
GST_DEBUG_OBJECT(self, "key received");
priv->keyReceived = true;
- priv->waitingForKey = false;
- gst_element_post_message(GST_ELEMENT(self), gst_message_new_element(GST_OBJECT(self), gst_structure_new_empty("drm-key-received")));
priv->condition.notifyOne();
- } else if (priv->waitingForKey) {
- GST_DEBUG_OBJECT(self, "still waiting for key, reposting");
- gst_element_post_message(GST_ELEMENT(self), gst_message_new_element(GST_OBJECT(self), gst_structure_new_empty("drm-waiting-for-key")));
}
gst_event_unref(event);
@@ -326,6 +326,16 @@
return result;
}
+static gboolean webkitMediaCommonEncryptionDecryptorQueryHandler(GstBaseTransform* trans, GstPadDirection direction, GstQuery* query)
+{
+ if (gst_structure_has_name(gst_query_get_structure(query), "any-decryptor-waiting-for-key")) {
+ WebKitMediaCommonEncryptionDecryptPrivate* priv = WEBKIT_MEDIA_CENC_DECRYPT_GET_PRIVATE(trans);
+ GST_TRACE_OBJECT(trans, "any-decryptor-waiting-for-key query, waitingforkey %s", boolForPrinting(priv->waitingForKey));
+ return priv->waitingForKey;
+ }
+ return GST_BASE_TRANSFORM_CLASS(parent_class)->query(trans, direction, query);
+}
+
static GstStateChangeReturn webKitMediaCommonEncryptionDecryptorChangeState(GstElement* element, GstStateChange transition)
{
WebKitMediaCommonEncryptionDecrypt* self = WEBKIT_MEDIA_CENC_DECRYPT(element);