GStreamerEMEUtilities.h [plain text]
#pragma once
#if ENABLE(ENCRYPTED_MEDIA) && USE(GSTREAMER)
#include "GStreamerCommon.h"
#include "SharedBuffer.h"
#include <gst/gst.h>
#include <wtf/text/WTFString.h>
#define WEBCORE_GSTREAMER_EME_UTILITIES_CLEARKEY_UUID "1077efec-c0b2-4d02-ace3-3c1e52e2fb4b"
#if ENABLE(THUNDER)
#define WEBCORE_GSTREAMER_EME_UTILITIES_WIDEVINE_UUID "edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"
#endif
GST_DEBUG_CATEGORY_EXTERN(webkit_media_common_encryption_decrypt_debug_category);
namespace WebCore {
class InitData {
public:
InitData()
: m_payload(SharedBuffer::create()) { }
InitData(const String& systemId, GstBuffer* initData)
: m_systemId(systemId)
{
auto mappedInitData = GstMappedOwnedBuffer::create(initData);
if (!mappedInitData) {
GST_CAT_LEVEL_LOG(webkit_media_common_encryption_decrypt_debug_category, GST_LEVEL_ERROR, nullptr, "cannot map %s protection data", systemId.utf8().data());
ASSERT_NOT_REACHED();
}
m_payload = mappedInitData->createSharedBuffer();
}
InitData(const String& systemId, RefPtr<SharedBuffer>&& payload)
: m_systemId(systemId)
, m_payload(WTFMove(payload))
{
}
void append(InitData&& initData)
{
m_systemId = initData.m_systemId;
m_payload->append(*initData.payload());
}
const RefPtr<SharedBuffer>& payload() const { return m_payload; }
const String& systemId() const { return m_systemId; }
String payloadContainerType() const
{
#if GST_CHECK_VERSION(1, 15, 0)
if (m_systemId == GST_PROTECTION_UNSPECIFIED_SYSTEM_ID)
return "webm"_s;
#endif
return "cenc"_s;
}
private:
String m_systemId;
RefPtr<SharedBuffer> m_payload;
};
class ProtectionSystemEvents {
public:
using EventVector = Vector<GRefPtr<GstEvent>>;
explicit ProtectionSystemEvents(GstMessage* message)
{
const GstStructure* structure = gst_message_get_structure(message);
const GValue* streamEncryptionEventsList = gst_structure_get_value(structure, "stream-encryption-events");
ASSERT(streamEncryptionEventsList && GST_VALUE_HOLDS_LIST(streamEncryptionEventsList));
unsigned numEvents = gst_value_list_get_size(streamEncryptionEventsList);
m_events.reserveInitialCapacity(numEvents);
for (unsigned i = 0; i < numEvents; ++i)
m_events.uncheckedAppend(GRefPtr<GstEvent>(static_cast<GstEvent*>(g_value_get_boxed(gst_value_list_get_value(streamEncryptionEventsList, i)))));
const GValue* streamEncryptionAllowedSystemsValue = gst_structure_get_value(structure, "available-stream-encryption-systems");
const char** streamEncryptionAllowedSystems = reinterpret_cast<const char**>(g_value_get_boxed(streamEncryptionAllowedSystemsValue));
if (streamEncryptionAllowedSystems) {
for (unsigned i = 0; streamEncryptionAllowedSystems[i]; ++i)
m_availableSystems.append(streamEncryptionAllowedSystems[i]);
}
}
const EventVector& events() const { return m_events; }
const Vector<String>& availableSystems() const { return m_availableSystems; }
private:
EventVector m_events;
Vector<String> m_availableSystems;
};
class GStreamerEMEUtilities {
public:
static constexpr char const* s_ClearKeyUUID = WEBCORE_GSTREAMER_EME_UTILITIES_CLEARKEY_UUID;
static constexpr char const* s_ClearKeyKeySystem = "org.w3.clearkey";
#if ENABLE(THUNDER)
static constexpr char const* s_WidevineUUID = WEBCORE_GSTREAMER_EME_UTILITIES_WIDEVINE_UUID;
static constexpr char const* s_WidevineKeySystem = "com.widevine.alpha";
#endif
static bool isClearKeyKeySystem(const String& keySystem)
{
return equalIgnoringASCIICase(keySystem, s_ClearKeyKeySystem);
}
#if ENABLE(THUNDER)
static bool isWidevineKeySystem(const String& keySystem)
{
return equalIgnoringASCIICase(keySystem, s_WidevineKeySystem);
}
#endif
static const char* keySystemToUuid(const String& keySystem)
{
if (isClearKeyKeySystem(keySystem))
return s_ClearKeyUUID;
#if ENABLE(THUNDER)
if (isWidevineKeySystem(keySystem))
return s_WidevineUUID;
#endif
ASSERT_NOT_REACHED();
return { };
}
};
}
#endif // ENABLE(ENCRYPTED_MEDIA) && USE(GSTREAMER)