Changeset 179641 in webkit


Ignore:
Timestamp:
Feb 4, 2015 3:27:11 PM (9 years ago)
Author:
jer.noble@apple.com
Message:

[Mac][EME] Support ClearKey encryption with AES128-encrypted HLS
https://bugs.webkit.org/show_bug.cgi?id=140825

Reviewed by Eric Carlson.

Source/WebCore:

Test: http/tests/media/clearkey/clear-key-hls-aes128.html

Add support for ClearKey encryption when used with an AES-128 encrypted HLS stream.

  • Modules/encryptedmedia/CDM.cpp:

(WebCore::installedCDMFactories): Add the CDMPrivateClearKey factory.

  • Modules/encryptedmedia/CDMPrivateClearKey.cpp:

(WebCore::CDMPrivateClearKey::supportsKeySystem): Support the "org.w3c.clearkey" key system.
(WebCore::CDMPrivateClearKey::supportsKeySystemAndMimeType): Ditto.
(WebCore::CDMPrivateClearKey::supportsMIMEType): Ditto.
(WebCore::CDMPrivateClearKey::createSession): Create a CDMSessionClearKey.

  • Modules/encryptedmedia/CDMPrivateClearKey.h:

(WebCore::CDMPrivateClearKey::create): Simple factory.
(WebCore::CDMPrivateClearKey::~CDMPrivateClearKey): Virtual destructor.
(WebCore::CDMPrivateClearKey::CDMPrivateClearKey): Simple destructor.

  • Modules/encryptedmedia/CDMSessionClearKey.cpp: Added.

(WebCore::clearKeyVM): Static method returning the VM to be used by JSON parsing.
(WebCore::CDMSessionClearKey::CDMSessionClearKey): Simple constructor.
(WebCore::CDMSessionClearKey::~CDMSessionClearKey): Simple destructor.
(WebCore::CDMSessionClearKey::generateKeyRequest): Store the initData, ensure that it consists of a UTF8-encoded key

URI, and return same.

(WebCore::CDMSessionClearKey::releaseKeys): Purged all cached keys.
(WebCore::CDMSessionClearKey::update): Parse raw JSON-encoded JWK keys, rejecting non-AES, non-oct keys.
(WebCore::CDMSessionClearKey::cachedKeyForKeyID): Return cached keys.

  • Modules/encryptedmedia/CDMSessionClearKey.h:

Add support for the "org.w3c.clearkey" CDM to MediaPlayerPrivateAVFoundationObjC, and do so in a platform-agnostic
way by simply asking for raw key data from MediaPlayerClient when notified that a key has been added.

  • platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
  • platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:

(WebCore::keySystemIsSupported):
(WebCore::MediaPlayerPrivateAVFoundationObjC::supportsType):
(WebCore::MediaPlayerPrivateAVFoundationObjC::supportsKeySystem):
(WebCore::fulfillRequestWithKeyData): Added utility method.
(WebCore::MediaPlayerPrivateAVFoundationObjC::shouldWaitForLoadingOfResource):
(WebCore::MediaPlayerPrivateAVFoundationObjC::keyAdded):

Pipe a keyAdded() notification down to MediaPlayer and a cachedKeyForKeyId() request up to CDMSessionClearKey:

  • Modules/encryptedmedia/MediaKeySession.cpp:

(WebCore::MediaKeySession::cachedKeyForKeyId):
(WebCore::MediaKeySession::addKeyTimerFired):

  • Modules/encryptedmedia/MediaKeySession.h:
  • Modules/encryptedmedia/MediaKeys.cpp:

(WebCore::MediaKeys::keyAdded):
(WebCore::MediaKeys::cachedKeyForKeyId):

  • Modules/encryptedmedia/MediaKeys.h:
  • html/HTMLMediaElement.cpp:

(WebCore::HTMLMediaElement::keyAdded):

  • html/HTMLMediaElement.h:
  • platform/graphics/CDMSession.h:

(WebCore::CDMSession::cachedKeyForKeyID):

  • platform/graphics/MediaPlayer.cpp:

(WebCore::MediaPlayer::keyAdded):
(WebCore::MediaPlayer::cachedKeyForKeyId):

  • platform/graphics/MediaPlayer.h:

(WebCore::MediaPlayerClient::mediaPlayerCachedKeyForKeyId):

  • platform/graphics/MediaPlayerPrivate.h:

(WebCore::MediaPlayerPrivateInterface::keyAdded):

Add new files to project:

  • WebCore.xcodeproj/project.pbxproj:
  • CMakeLists.txt:
  • WebCore.vcxproj/WebCore.vcxproj:
  • WebCore.vcxproj/WebCore.vcxproj.filters:

LayoutTests:

  • http/tests/media/clearkey/clear-key-hls-aes128-expected.txt: Added.
  • http/tests/media/clearkey/clear-key-hls-aes128.html: Added.
  • http/tests/media/clearkey/support.js: Added.

(stringToUInt8Array):
(uInt8ArrayToString):
(base64EncodeUint8Array):

  • http/tests/media/resources/hls/clearkey/crypt0.key: Added.
  • http/tests/media/resources/hls/clearkey/iframe_index.m3u8: Added.
  • http/tests/media/resources/hls/clearkey/main0.ts: Added.
  • http/tests/media/resources/hls/clearkey/prog_index.m3u8: Added.
  • media/video-test.js:

(waitForEventOnceOn):

Location:
trunk
Files:
10 added
20 edited
3 copied

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r179638 r179641  
     12015-02-04  Jer Noble  <jer.noble@apple.com>
     2
     3        [Mac][EME] Support ClearKey encryption with AES128-encrypted HLS
     4        https://bugs.webkit.org/show_bug.cgi?id=140825
     5
     6        Reviewed by Eric Carlson.
     7
     8        * http/tests/media/clearkey/clear-key-hls-aes128-expected.txt: Added.
     9        * http/tests/media/clearkey/clear-key-hls-aes128.html: Added.
     10        * http/tests/media/clearkey/support.js: Added.
     11        (stringToUInt8Array):
     12        (uInt8ArrayToString):
     13        (base64EncodeUint8Array):
     14        * http/tests/media/resources/hls/clearkey/crypt0.key: Added.
     15        * http/tests/media/resources/hls/clearkey/iframe_index.m3u8: Added.
     16        * http/tests/media/resources/hls/clearkey/main0.ts: Added.
     17        * http/tests/media/resources/hls/clearkey/prog_index.m3u8: Added.
     18        * media/video-test.js:
     19        (waitForEventOnceOn):
     20
    1212015-02-04  Commit Queue  <commit-queue@webkit.org>
    222
  • trunk/LayoutTests/media/video-test.js

    r179054 r179641  
    204204}
    205205
     206function waitForEventOnceOn(element, eventName, func, endit)
     207{
     208    waitForEventOn(element, eventName, func, endit, true);
     209}
     210
    206211function waitForEventOn(element, eventName, func, endit, oneTimeOnly)
    207212{
  • trunk/Source/WebCore/CMakeLists.txt

    r179534 r179641  
    27352735        Modules/encryptedmedia/CDM.cpp
    27362736        Modules/encryptedmedia/CDMPrivateMediaPlayer.cpp
     2737        Modules/encryptedmedia/CDMPrivateClearKey.cpp
     2738        Modules/encryptedmedia/CDMSessionClearKey.cpp
    27372739        Modules/encryptedmedia/MediaKeyMessageEvent.cpp
    27382740        Modules/encryptedmedia/MediaKeyNeededEvent.cpp
  • trunk/Source/WebCore/ChangeLog

    r179638 r179641  
     12015-02-04  Jer Noble  <jer.noble@apple.com>
     2
     3        [Mac][EME] Support ClearKey encryption with AES128-encrypted HLS
     4        https://bugs.webkit.org/show_bug.cgi?id=140825
     5
     6        Reviewed by Eric Carlson.
     7
     8        Test: http/tests/media/clearkey/clear-key-hls-aes128.html
     9
     10        Add support for ClearKey encryption when used with an AES-128 encrypted HLS stream.
     11
     12        * Modules/encryptedmedia/CDM.cpp:
     13        (WebCore::installedCDMFactories): Add the CDMPrivateClearKey factory.
     14        * Modules/encryptedmedia/CDMPrivateClearKey.cpp:
     15        (WebCore::CDMPrivateClearKey::supportsKeySystem): Support the "org.w3c.clearkey" key system.
     16        (WebCore::CDMPrivateClearKey::supportsKeySystemAndMimeType): Ditto.
     17        (WebCore::CDMPrivateClearKey::supportsMIMEType): Ditto.
     18        (WebCore::CDMPrivateClearKey::createSession): Create a CDMSessionClearKey.
     19        * Modules/encryptedmedia/CDMPrivateClearKey.h:
     20        (WebCore::CDMPrivateClearKey::create): Simple factory.
     21        (WebCore::CDMPrivateClearKey::~CDMPrivateClearKey): Virtual destructor.
     22        (WebCore::CDMPrivateClearKey::CDMPrivateClearKey): Simple destructor.
     23        * Modules/encryptedmedia/CDMSessionClearKey.cpp: Added.
     24        (WebCore::clearKeyVM): Static method returning the VM to be used by JSON parsing.
     25        (WebCore::CDMSessionClearKey::CDMSessionClearKey): Simple constructor.
     26        (WebCore::CDMSessionClearKey::~CDMSessionClearKey): Simple destructor.
     27        (WebCore::CDMSessionClearKey::generateKeyRequest): Store the initData, ensure that it consists of a UTF8-encoded key
     28            URI, and return same.
     29        (WebCore::CDMSessionClearKey::releaseKeys): Purged all cached keys.
     30        (WebCore::CDMSessionClearKey::update): Parse raw JSON-encoded JWK keys, rejecting non-AES, non-oct keys.
     31        (WebCore::CDMSessionClearKey::cachedKeyForKeyID): Return cached keys.
     32        * Modules/encryptedmedia/CDMSessionClearKey.h:
     33
     34        Add support for the "org.w3c.clearkey" CDM to MediaPlayerPrivateAVFoundationObjC, and do so in a platform-agnostic
     35        way by simply asking for raw key data from MediaPlayerClient when notified that a key has been added.
     36
     37        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
     38        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
     39        (WebCore::keySystemIsSupported):
     40        (WebCore::MediaPlayerPrivateAVFoundationObjC::supportsType):
     41        (WebCore::MediaPlayerPrivateAVFoundationObjC::supportsKeySystem):
     42        (WebCore::fulfillRequestWithKeyData): Added utility method.
     43        (WebCore::MediaPlayerPrivateAVFoundationObjC::shouldWaitForLoadingOfResource):
     44        (WebCore::MediaPlayerPrivateAVFoundationObjC::keyAdded):
     45
     46        Pipe a keyAdded() notification down to MediaPlayer and a cachedKeyForKeyId() request up to CDMSessionClearKey:
     47
     48        * Modules/encryptedmedia/MediaKeySession.cpp:
     49        (WebCore::MediaKeySession::cachedKeyForKeyId):
     50        (WebCore::MediaKeySession::addKeyTimerFired):
     51        * Modules/encryptedmedia/MediaKeySession.h:
     52        * Modules/encryptedmedia/MediaKeys.cpp:
     53        (WebCore::MediaKeys::keyAdded):
     54        (WebCore::MediaKeys::cachedKeyForKeyId):
     55        * Modules/encryptedmedia/MediaKeys.h:
     56        * html/HTMLMediaElement.cpp:
     57        (WebCore::HTMLMediaElement::keyAdded):
     58        * html/HTMLMediaElement.h:
     59        * platform/graphics/CDMSession.h:
     60        (WebCore::CDMSession::cachedKeyForKeyID):
     61        * platform/graphics/MediaPlayer.cpp:
     62        (WebCore::MediaPlayer::keyAdded):
     63        (WebCore::MediaPlayer::cachedKeyForKeyId):
     64        * platform/graphics/MediaPlayer.h:
     65        (WebCore::MediaPlayerClient::mediaPlayerCachedKeyForKeyId):
     66        * platform/graphics/MediaPlayerPrivate.h:
     67        (WebCore::MediaPlayerPrivateInterface::keyAdded):
     68
     69        Add new files to project:
     70
     71        * WebCore.xcodeproj/project.pbxproj:
     72        * CMakeLists.txt:
     73        * WebCore.vcxproj/WebCore.vcxproj:
     74        * WebCore.vcxproj/WebCore.vcxproj.filters:
     75
    1762015-02-04  Commit Queue  <commit-queue@webkit.org>
    277
  • trunk/Source/WebCore/Modules/encryptedmedia/CDM.cpp

    r179054 r179641  
    3030#include "CDM.h"
    3131
     32#include "CDMPrivateClearKey.h"
    3233#include "CDMPrivateMediaPlayer.h"
    3334#include "CDMSession.h"
     
    6566    if (!queriedCDMs) {
    6667        queriedCDMs = true;
     68
     69        cdms.get().append(new CDMFactory(CDMPrivateClearKey::create, CDMPrivateClearKey::supportsKeySystem, CDMPrivateClearKey::supportsKeySystemAndMimeType));
    6770
    6871        // FIXME: initialize specific UA CDMs. http://webkit.org/b/109318, http://webkit.org/b/109320
  • trunk/Source/WebCore/Modules/encryptedmedia/CDMPrivateClearKey.cpp

    r179640 r179641  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
    3  *
     2 * Copyright (C) 2015 Apple Inc. All rights reserved.
     3 * 
    44 * Redistribution and use in source and binary forms, with or without
    55 * modification, are permitted provided that the following conditions
     
    2424 */
    2525
    26 #ifndef MediaKeys_h
    27 #define MediaKeys_h
     26#include "config.h"
     27#include "CDMPrivateClearKey.h"
    2828
    2929#if ENABLE(ENCRYPTED_MEDIA_V2)
    3030
    3131#include "CDM.h"
    32 #include "EventTarget.h"
     32#include "CDMSessionClearKey.h"
     33#include "ContentType.h"
    3334#include "ExceptionCode.h"
    34 #include <runtime/Uint8Array.h>
    35 #include <wtf/PassRefPtr.h>
    36 #include <wtf/RefCounted.h>
    37 #include <wtf/Vector.h>
    38 #include <wtf/text/WTFString.h>
     35#include "MediaPlayer.h"
    3936
    4037namespace WebCore {
    4138
    42 class MediaKeySession;
    43 class HTMLMediaElement;
     39bool CDMPrivateClearKey::supportsKeySystem(const String& keySystem)
     40{
     41    if (!equalIgnoringCase(keySystem, "org.w3c.clearkey"))
     42        return false;
    4443
    45 class MediaKeys : public RefCounted<MediaKeys>, public CDMClient {
    46 public:
    47     static PassRefPtr<MediaKeys> create(const String& keySystem, ExceptionCode&);
    48     virtual ~MediaKeys();
     44    // The MediaPlayer must also support the key system:
     45    return MediaPlayer::supportsKeySystem(keySystem, emptyString());
     46}
    4947
    50     PassRefPtr<MediaKeySession> createSession(ScriptExecutionContext*, const String& mimeType, Uint8Array* initData, ExceptionCode&);
     48bool CDMPrivateClearKey::supportsKeySystemAndMimeType(const String& keySystem, const String& mimeType)
     49{
     50    if (!equalIgnoringCase(keySystem, "org.w3c.clearkey"))
     51        return false;
    5152
    52     static bool isTypeSupported(const String& keySystem, const String& mimeType);
     53    // The MediaPlayer must also support the key system:
     54    return MediaPlayer::supportsKeySystem(keySystem, mimeType);
     55}
    5356
    54     const String& keySystem() const { return m_keySystem; }
    55     CDM* cdm() { return m_cdm.get(); }
     57bool CDMPrivateClearKey::supportsMIMEType(const String& mimeType)
     58{
     59    return MediaPlayer::supportsKeySystem(m_cdm->keySystem(), mimeType);
     60}
    5661
    57     HTMLMediaElement* mediaElement() const { return m_mediaElement; }
    58     void setMediaElement(HTMLMediaElement*);
    59 
    60 protected:
    61     // CDMClient:
    62     virtual MediaPlayer* cdmMediaPlayer(const CDM*) const override;
    63 
    64     MediaKeys(const String& keySystem, std::unique_ptr<CDM>);
    65 
    66     Vector<RefPtr<MediaKeySession>> m_sessions;
    67 
    68     HTMLMediaElement* m_mediaElement;
    69     String m_keySystem;
    70     std::unique_ptr<CDM> m_cdm;
    71 };
     62std::unique_ptr<CDMSession> CDMPrivateClearKey::createSession()
     63{
     64    return std::make_unique<CDMSessionClearKey>();
     65}
    7266
    7367}
    7468
    75 #endif // ENABLE(ENCRYPTED_MEDIA_V2)
    76 
    77 #endif // MediaKeys_h
     69#endif
  • trunk/Source/WebCore/Modules/encryptedmedia/CDMPrivateClearKey.h

    r179640 r179641  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 #ifndef MediaKeys_h
    27 #define MediaKeys_h
     26#ifndef CDMPrivateClearKey_h
     27#define CDMPrivateClearKey_h
    2828
    2929#if ENABLE(ENCRYPTED_MEDIA_V2)
    3030
    31 #include "CDM.h"
    32 #include "EventTarget.h"
    33 #include "ExceptionCode.h"
    34 #include <runtime/Uint8Array.h>
    35 #include <wtf/PassRefPtr.h>
    36 #include <wtf/RefCounted.h>
    37 #include <wtf/Vector.h>
    38 #include <wtf/text/WTFString.h>
     31#include "CDMPrivate.h"
    3932
    4033namespace WebCore {
    4134
    42 class MediaKeySession;
    43 class HTMLMediaElement;
     35class CDM;
    4436
    45 class MediaKeys : public RefCounted<MediaKeys>, public CDMClient {
     37class CDMPrivateClearKey : public CDMPrivateInterface {
    4638public:
    47     static PassRefPtr<MediaKeys> create(const String& keySystem, ExceptionCode&);
    48     virtual ~MediaKeys();
     39    static std::unique_ptr<CDMPrivateInterface> create(CDM* cdm) { return std::unique_ptr<CDMPrivateInterface>(new CDMPrivateClearKey(cdm)); }
     40    virtual ~CDMPrivateClearKey() { }
    4941
    50     PassRefPtr<MediaKeySession> createSession(ScriptExecutionContext*, const String& mimeType, Uint8Array* initData, ExceptionCode&);
     42    static bool supportsKeySystem(const String&);
     43    static bool supportsKeySystemAndMimeType(const String& keySystem, const String& mimeType);
    5144
    52     static bool isTypeSupported(const String& keySystem, const String& mimeType);
    53 
    54     const String& keySystem() const { return m_keySystem; }
    55     CDM* cdm() { return m_cdm.get(); }
    56 
    57     HTMLMediaElement* mediaElement() const { return m_mediaElement; }
    58     void setMediaElement(HTMLMediaElement*);
     45    virtual bool supportsMIMEType(const String& mimeType) override;
     46    virtual std::unique_ptr<CDMSession> createSession() override;
    5947
    6048protected:
    61     // CDMClient:
    62     virtual MediaPlayer* cdmMediaPlayer(const CDM*) const override;
     49    explicit CDMPrivateClearKey(CDM* cdm)
     50        : m_cdm(cdm)
     51    {
     52    }
    6353
    64     MediaKeys(const String& keySystem, std::unique_ptr<CDM>);
    65 
    66     Vector<RefPtr<MediaKeySession>> m_sessions;
    67 
    68     HTMLMediaElement* m_mediaElement;
    69     String m_keySystem;
    70     std::unique_ptr<CDM> m_cdm;
     54    CDM* m_cdm;
    7155};
    7256
     
    7559#endif // ENABLE(ENCRYPTED_MEDIA_V2)
    7660
    77 #endif // MediaKeys_h
     61#endif // CDMPrivateClearKey_h
  • trunk/Source/WebCore/Modules/encryptedmedia/CDMSessionClearKey.h

    r179640 r179641  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 #ifndef MediaKeys_h
    27 #define MediaKeys_h
     26#ifndef CDMSessionClearKey_h
     27#define CDMSessionClearKey_h
     28
     29#include "CDMSession.h"
     30#include <wtf/HashMap.h>
    2831
    2932#if ENABLE(ENCRYPTED_MEDIA_V2)
    3033
    31 #include "CDM.h"
    32 #include "EventTarget.h"
    33 #include "ExceptionCode.h"
    34 #include <runtime/Uint8Array.h>
    35 #include <wtf/PassRefPtr.h>
    36 #include <wtf/RefCounted.h>
    37 #include <wtf/Vector.h>
    38 #include <wtf/text/WTFString.h>
    39 
    4034namespace WebCore {
    4135
    42 class MediaKeySession;
    43 class HTMLMediaElement;
     36class CDMSessionClearKey : public CDMSession {
     37public:
     38    CDMSessionClearKey();
     39    virtual ~CDMSessionClearKey();
    4440
    45 class MediaKeys : public RefCounted<MediaKeys>, public CDMClient {
    46 public:
    47     static PassRefPtr<MediaKeys> create(const String& keySystem, ExceptionCode&);
    48     virtual ~MediaKeys();
    49 
    50     PassRefPtr<MediaKeySession> createSession(ScriptExecutionContext*, const String& mimeType, Uint8Array* initData, ExceptionCode&);
    51 
    52     static bool isTypeSupported(const String& keySystem, const String& mimeType);
    53 
    54     const String& keySystem() const { return m_keySystem; }
    55     CDM* cdm() { return m_cdm.get(); }
    56 
    57     HTMLMediaElement* mediaElement() const { return m_mediaElement; }
    58     void setMediaElement(HTMLMediaElement*);
     41    // CDMSessionPrivate
     42    virtual CDMSessionType type() override { return CDMSessionTypeClearKey; }
     43    virtual void setClient(CDMSessionClient* client) override { m_client = client; }
     44    virtual const String& sessionId() const override { return m_sessionId; }
     45    virtual PassRefPtr<Uint8Array> generateKeyRequest(const String& mimeType, Uint8Array*, String&, unsigned short&, unsigned long&) override;
     46    virtual void releaseKeys() override;
     47    virtual bool update(Uint8Array*, RefPtr<Uint8Array>&, unsigned short&, unsigned long&) override;
     48    virtual RefPtr<ArrayBuffer> cachedKeyForKeyID(const String&) const override;
    5949
    6050protected:
    61     // CDMClient:
    62     virtual MediaPlayer* cdmMediaPlayer(const CDM*) const override;
    63 
    64     MediaKeys(const String& keySystem, std::unique_ptr<CDM>);
    65 
    66     Vector<RefPtr<MediaKeySession>> m_sessions;
    67 
    68     HTMLMediaElement* m_mediaElement;
    69     String m_keySystem;
    70     std::unique_ptr<CDM> m_cdm;
     51    CDMSessionClient* m_client;
     52    RefPtr<Uint8Array> m_initData;
     53    HashMap<String, Vector<uint8_t>> m_cachedKeys;
     54    String m_sessionId;
    7155};
    7256
     
    7559#endif // ENABLE(ENCRYPTED_MEDIA_V2)
    7660
    77 #endif // MediaKeys_h
     61#endif // CDMSessionClearKey_h
  • trunk/Source/WebCore/Modules/encryptedmedia/MediaKeySession.cpp

    r179054 r179641  
    8181}
    8282
     83RefPtr<ArrayBuffer> MediaKeySession::cachedKeyForKeyId(const String& keyId) const
     84{
     85    return m_session ? m_session->cachedKeyForKeyID(keyId) : nullptr;
     86}
     87
    8388const String& MediaKeySession::sessionId() const
    8489{
     
    185190            keyaddedEvent->setTarget(this);
    186191            m_asyncEventQueue.enqueueEvent(keyaddedEvent.release());
     192
     193            keys()->keyAdded();
    187194        }
    188195
  • trunk/Source/WebCore/Modules/encryptedmedia/MediaKeySession.h

    r179054 r179641  
    6767    void close();
    6868
     69    RefPtr<ArrayBuffer> cachedKeyForKeyId(const String& keyId) const;
     70
    6971    using RefCounted<MediaKeySession>::ref;
    7072    using RefCounted<MediaKeySession>::deref;
  • trunk/Source/WebCore/Modules/encryptedmedia/MediaKeys.cpp

    r179054 r179641  
    161161}
    162162
     163void MediaKeys::keyAdded()
     164{
     165    if (m_mediaElement)
     166        m_mediaElement->keyAdded();
     167
     168}
     169
     170RefPtr<ArrayBuffer> MediaKeys::cachedKeyForKeyId(const String& keyId) const
     171{
     172    for (auto& session : m_sessions) {
     173        if (RefPtr<ArrayBuffer> key = session->cachedKeyForKeyId(keyId))
     174            return key;
     175    }
     176    return nullptr;
     177}
     178
    163179}
    164180
  • trunk/Source/WebCore/Modules/encryptedmedia/MediaKeys.h

    r179054 r179641  
    5858    void setMediaElement(HTMLMediaElement*);
    5959
     60    void keyAdded();
     61    RefPtr<ArrayBuffer> cachedKeyForKeyId(const String& keyId) const;
     62
    6063protected:
    6164    // CDMClient:
  • trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj

    r179534 r179641  
    67956795    <ClCompile Include="..\Modules\encryptedmedia\CDM.cpp" />
    67966796    <ClCompile Include="..\Modules\encryptedmedia\CDMPrivateMediaPlayer.cpp" />
     6797    <ClCompile Include="..\Modules\encryptedmedia\CDMPrivateClearKey.cpp" />
     6798    <ClCompile Include="..\Modules\encryptedmedia\CDMSessionClearKey.cpp" />
    67976799    <ClCompile Include="..\Modules\encryptedmedia\MediaKeyMessageEvent.cpp" />
    67986800    <ClCompile Include="..\Modules\encryptedmedia\MediaKeyNeededEvent.cpp" />
     
    1900519007    <ClInclude Include="..\Modules\encryptedmedia\CDMPrivate.h" />
    1900619008    <ClInclude Include="..\Modules\encryptedmedia\CDMPrivateMediaPlayer.h" />
     19009    <ClInclude Include="..\Modules\encryptedmedia\CDMPrivateClearKey.h" />
     19010    <ClInclude Include="..\Modules\encryptedmedia\CDMSessionClearKey.h" />
    1900719011    <ClInclude Include="..\Modules\encryptedmedia\MediaKeyMessageEvent.h" />
    1900819012    <ClInclude Include="..\Modules\encryptedmedia\MediaKeyNeededEvent.h" />
  • trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters

    r179534 r179641  
    69206920      <Filter>Modules\encryptedmedia</Filter>
    69216921    </ClCompile>
     6922    <ClCompile Include="..\Modules\encryptedmedia\CDMPrivateClearKey.cpp">
     6923      <Filter>Modules\encryptedmedia</Filter>
     6924    </ClCompile>
     6925    <ClCompile Include="..\Modules\encryptedmedia\CDMSessionClearKey.cpp">
     6926      <Filter>Modules\encryptedmedia</Filter>
     6927    </ClCompile>
    69226928    <ClCompile Include="..\Modules\encryptedmedia\MediaKeyMessageEvent.cpp">
    69236929      <Filter>Modules\encryptedmedia</Filter>
     
    1490714913    <ClInclude Include="..\svg\SVGURIReference.h">
    1490814914      <Filter>svg</Filter>
     14915    <ClInclude Include="..\Modules\encryptedmedia\CDMPrivateClearKey.h">
     14916      <Filter>Modules\encryptedmedia</Filter>
     14917    </ClInclude>
     14918    <ClInclude Include="..\Modules\encryptedmedia\CDMSessionClearKey.h">
     14919      <Filter>Modules\encryptedmedia</Filter>
     14920    </ClInclude>
     14921    <ClInclude Include="..\Modules\encryptedmedia\MediaKeyMessageEvent.h">
     14922      <Filter>Modules\encryptedmedia</Filter>
    1490914923    </ClInclude>
    1491014924    <ClInclude Include="..\svg\SVGUseElement.h">
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r179626 r179641  
    57495749                CDE83DB2183C44060031EAA3 /* VideoPlaybackQuality.h in Headers */ = {isa = PBXBuildFile; fileRef = CDE83DB0183C44060031EAA3 /* VideoPlaybackQuality.h */; };
    57505750                CDE83DB6183D352A0031EAA3 /* JSVideoPlaybackQuality.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDE83DB4183D352A0031EAA3 /* JSVideoPlaybackQuality.cpp */; };
     5751                CDE8B5EC1A69777300B4B66A /* CDMPrivateClearKey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDE8B5EA1A69777300B4B66A /* CDMPrivateClearKey.cpp */; };
     5752                CDE8B5ED1A69777300B4B66A /* CDMPrivateClearKey.h in Headers */ = {isa = PBXBuildFile; fileRef = CDE8B5EB1A69777300B4B66A /* CDMPrivateClearKey.h */; };
     5753                CDE8B5F01A69778B00B4B66A /* CDMSessionClearKey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDE8B5EE1A69778B00B4B66A /* CDMSessionClearKey.cpp */; };
     5754                CDE8B5F11A69778B00B4B66A /* CDMSessionClearKey.h in Headers */ = {isa = PBXBuildFile; fileRef = CDE8B5EF1A69778B00B4B66A /* CDMSessionClearKey.h */; };
    57515755                CDEA763014608A53008B31F1 /* PlatformClockCA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDEA762E146084DE008B31F1 /* PlatformClockCA.cpp */; };
    57525756                CDEA76341460B56F008B31F1 /* ClockGeneric.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDEA76321460AE29008B31F1 /* ClockGeneric.cpp */; };
     
    1325013254                CDE83DB4183D352A0031EAA3 /* JSVideoPlaybackQuality.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSVideoPlaybackQuality.cpp; sourceTree = "<group>"; };
    1325113255                CDE83DB5183D352A0031EAA3 /* JSVideoPlaybackQuality.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSVideoPlaybackQuality.h; sourceTree = "<group>"; };
     13256                CDE8B5EA1A69777300B4B66A /* CDMPrivateClearKey.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CDMPrivateClearKey.cpp; sourceTree = "<group>"; };
     13257                CDE8B5EB1A69777300B4B66A /* CDMPrivateClearKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDMPrivateClearKey.h; sourceTree = "<group>"; };
     13258                CDE8B5EE1A69778B00B4B66A /* CDMSessionClearKey.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CDMSessionClearKey.cpp; sourceTree = "<group>"; };
     13259                CDE8B5EF1A69778B00B4B66A /* CDMSessionClearKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDMSessionClearKey.h; sourceTree = "<group>"; };
    1325213260                CDEA762C14608224008B31F1 /* Clock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Clock.h; sourceTree = "<group>"; };
    1325313261                CDEA762E146084DE008B31F1 /* PlatformClockCA.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformClockCA.cpp; sourceTree = "<group>"; };
     
    2165021658                                CDA98DC816014F2C00FEA3B1 /* MediaKeySession.h */,
    2165121659                                CDA98DC916014F4000FEA3B1 /* MediaKeySession.idl */,
     21660                                CDE8B5EA1A69777300B4B66A /* CDMPrivateClearKey.cpp */,
     21661                                CDE8B5EB1A69777300B4B66A /* CDMPrivateClearKey.h */,
     21662                                CDE8B5EE1A69778B00B4B66A /* CDMSessionClearKey.cpp */,
     21663                                CDE8B5EF1A69778B00B4B66A /* CDMSessionClearKey.h */,
    2165221664                        );
    2165321665                        path = encryptedmedia;
     
    2575525767                                F55B3DCE1251F12D003EF269 /* RangeInputType.h in Headers */,
    2575625768                                6E84E9E117668BF100815B68 /* RasterShape.h in Headers */,
     25769                                CDE8B5F11A69778B00B4B66A /* CDMSessionClearKey.h in Headers */,
    2575725770                                A84D827C11D333ED00972990 /* RawDataDocumentParser.h in Headers */,
    2575825771                                FD31603C12B0267600C1A359 /* RealtimeAnalyser.h in Headers */,
     
    2653626549                                930FC68A1072B9280045293E /* TextRenderingMode.h in Headers */,
    2653726550                                93F198F608245E59001E9ABC /* TextResourceDecoder.h in Headers */,
     26551                                CDE8B5ED1A69777300B4B66A /* CDMPrivateClearKey.h in Headers */,
    2653826552                                A824B4650E2EF2EA0081A7B7 /* TextRun.h in Headers */,
    2653926553                                448B1B7A0F3A2F9B0047A9E2 /* TextSizeAdjustment.h in Headers */,
     
    2833928353                                BCE438A2140C0DC0005E437E /* JSDictionary.cpp in Sources */,
    2834028354                                659DDC8209E198BA001BF3C6 /* JSDocument.cpp in Sources */,
     28355                                CDE8B5F01A69778B00B4B66A /* CDMSessionClearKey.cpp in Sources */,
    2834128356                                49C7BA8D1042F5B10009D447 /* JSDocumentCustom.cpp in Sources */,
    2834228357                                1A494EDE0A123F4C00FDAFC1 /* JSDocumentFragment.cpp in Sources */,
     
    2872028735                                8542A79A0AE5C94400DF58DF /* JSSVGElementWrapperFactory.cpp in Sources */,
    2872128736                                B2FA3D680AB75A6F000E5AC4 /* JSSVGEllipseElement.cpp in Sources */,
     28737                                CDE8B5EC1A69777300B4B66A /* CDMPrivateClearKey.cpp in Sources */,
    2872228738                                B266CD4D0C3AEC6500EB08D2 /* JSSVGException.cpp in Sources */,
    2872328739                                B2FA3D6A0AB75A6F000E5AC4 /* JSSVGFEBlendElement.cpp in Sources */,
  • trunk/Source/WebCore/html/HTMLMediaElement.cpp

    r179612 r179641  
    21832183
    21842184#if ENABLE(ENCRYPTED_MEDIA_V2)
     2185RefPtr<ArrayBuffer> HTMLMediaElement::mediaPlayerCachedKeyForKeyId(const String& keyId) const
     2186{
     2187    return m_mediaKeys ? m_mediaKeys->cachedKeyForKeyId(keyId) : nullptr;
     2188}
     2189
    21852190bool HTMLMediaElement::mediaPlayerKeyNeeded(MediaPlayer*, Uint8Array* initData)
    21862191{
     
    22302235    if (m_mediaKeys)
    22312236        m_mediaKeys->setMediaElement(this);
     2237}
     2238
     2239void HTMLMediaElement::keyAdded()
     2240{
     2241    if (m_player)
     2242        m_player->keyAdded();
    22322243}
    22332244#endif
  • trunk/Source/WebCore/html/HTMLMediaElement.h

    r179054 r179641  
    243243    MediaKeys* keys() const { return m_mediaKeys.get(); }
    244244    void setMediaKeys(MediaKeys*);
     245
     246    void keyAdded();
    245247#endif
    246248
     
    564566
    565567#if ENABLE(ENCRYPTED_MEDIA_V2)
     568    virtual RefPtr<ArrayBuffer> mediaPlayerCachedKeyForKeyId(const String& keyId) const override;
    566569    virtual bool mediaPlayerKeyNeeded(MediaPlayer*, Uint8Array*) override;
    567570    virtual String mediaPlayerMediaKeysStorageDirectory() const override;
  • trunk/Source/WebCore/platform/graphics/CDMSession.h

    r179054 r179641  
    5757enum CDMSessionType {
    5858    CDMSessionTypeUnknown,
     59    CDMSessionTypeClearKey,
    5960    CDMSessionTypeAVFoundationObjC,
    6061    CDMSessionTypeMediaSourceAVFObjC,
     
    7273    virtual void releaseKeys() = 0;
    7374    virtual bool update(Uint8Array*, RefPtr<Uint8Array>& nextMessage, unsigned short& errorCode, unsigned long& systemCode) = 0;
     75    virtual RefPtr<ArrayBuffer> cachedKeyForKeyID(const String&) const { return nullptr; }
    7476};
    7577
  • trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp

    r179246 r179641  
    484484    m_private->setCDMSession(session);
    485485}
     486
     487void MediaPlayer::keyAdded()
     488{
     489    m_private->keyAdded();
     490}
    486491#endif
    487492   
     
    10881093
    10891094#if ENABLE(ENCRYPTED_MEDIA_V2)
     1095RefPtr<ArrayBuffer> MediaPlayer::cachedKeyForKeyId(const String& keyId) const
     1096{
     1097    return m_client.mediaPlayerCachedKeyForKeyId(keyId);
     1098}
     1099
    10901100bool MediaPlayer::keyNeeded(Uint8Array* initData)
    10911101{
  • trunk/Source/WebCore/platform/graphics/MediaPlayer.h

    r179246 r179641  
    212212
    213213#if ENABLE(ENCRYPTED_MEDIA_V2)
     214    virtual RefPtr<ArrayBuffer> mediaPlayerCachedKeyForKeyId(const String&) const { return nullptr; }
    214215    virtual bool mediaPlayerKeyNeeded(MediaPlayer*, Uint8Array*) { return false; }
    215216    virtual String mediaPlayerMediaKeysStorageDirectory() const { return emptyString(); }
     
    352353    std::unique_ptr<CDMSession> createSession(const String& keySystem);
    353354    void setCDMSession(CDMSession*);
     355    void keyAdded();
    354356#endif
    355357
     
    518520
    519521#if ENABLE(ENCRYPTED_MEDIA_V2)
     522    RefPtr<ArrayBuffer> cachedKeyForKeyId(const String& keyId) const;
    520523    bool keyNeeded(Uint8Array* initData);
    521524    String mediaKeysStorageDirectory() const;
  • trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h

    r179054 r179641  
    226226    virtual std::unique_ptr<CDMSession> createSession(const String&) { return nullptr; }
    227227    virtual void setCDMSession(CDMSession*) { }
     228    virtual void keyAdded() { }
    228229#endif
    229230
  • trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h

    r179054 r179641  
    9292#if ENABLE(ENCRYPTED_MEDIA_V2)
    9393    RetainPtr<AVAssetResourceLoadingRequest> takeRequestForKeyURI(const String&);
     94    virtual void keyAdded() override;
    9495#endif
    9596
  • trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm

    r179574 r179641  
    5454#import "SerializedPlatformRepresentationMac.h"
    5555#import "SoftLinking.h"
     56#import "TextEncoding.h"
    5657#import "TextTrackRepresentation.h"
    5758#import "UUID.h"
     
    15191520static bool keySystemIsSupported(const String& keySystem)
    15201521{
    1521     if (equalIgnoringCase(keySystem, "com.apple.fps") || equalIgnoringCase(keySystem, "com.apple.fps.1_0"))
     1522    if (equalIgnoringCase(keySystem, "com.apple.fps") || equalIgnoringCase(keySystem, "com.apple.fps.1_0") || equalIgnoringCase(keySystem, "org.w3c.clearkey"))
    15221523        return true;
    15231524    return false;
     
    15341535    //    If keySystem is null, continue to the next step.
    15351536    if (!parameters.keySystem.isNull() && !parameters.keySystem.isEmpty()) {
     1537        // "Clear Key" is only supported with HLS:
     1538        if (equalIgnoringCase(parameters.keySystem, "org.w3c.clearkey") && !parameters.type.isEmpty() && !equalIgnoringCase(parameters.type, "application/x-mpegurl"))
     1539            return MediaPlayer::IsNotSupported;
     1540
    15361541        // If keySystem contains an unrecognized or unsupported Key System, return the empty string
    15371542        if (!keySystemIsSupported(parameters.keySystem))
     
    15661571#if ENABLE(ENCRYPTED_MEDIA) || ENABLE(ENCRYPTED_MEDIA_V2)
    15671572    if (!keySystem.isEmpty()) {
     1573        // "Clear Key" is only supported with HLS:
     1574        if (equalIgnoringCase(keySystem, "org.w3c.clearkey") && !mimeType.isEmpty() && !equalIgnoringCase(mimeType, "application/x-mpegurl"))
     1575            return MediaPlayer::IsNotSupported;
     1576
    15681577        if (!keySystemIsSupported(keySystem))
    15691578            return false;
     
    15821591
    15831592#if HAVE(AVFOUNDATION_LOADER_DELEGATE)
     1593#if ENABLE(ENCRYPTED_MEDIA_V2)
     1594static void fulfillRequestWithKeyData(AVAssetResourceLoadingRequest *request, ArrayBuffer* keyData)
     1595{
     1596    if (AVAssetResourceLoadingContentInformationRequest *infoRequest = [request contentInformationRequest]) {
     1597        [infoRequest setContentLength:keyData->byteLength()];
     1598        [infoRequest setByteRangeAccessSupported:YES];
     1599    }
     1600
     1601    if (AVAssetResourceLoadingDataRequest *dataRequest = [request dataRequest]) {
     1602        long long start = [dataRequest currentOffset];
     1603        long long end = std::min<long long>(keyData->byteLength(), [dataRequest currentOffset] + [dataRequest requestedLength]);
     1604
     1605        if (start < 0 || end < 0 || start >= static_cast<long long>(keyData->byteLength())) {
     1606            [request finishLoadingWithError:nil];
     1607            return;
     1608        }
     1609
     1610        ASSERT(start <= std::numeric_limits<int>::max());
     1611        ASSERT(end <= std::numeric_limits<int>::max());
     1612        RefPtr<ArrayBuffer> requestedKeyData = keyData->slice(static_cast<int>(start), static_cast<int>(end));
     1613        RetainPtr<NSData> nsData = adoptNS([[NSData alloc] initWithBytes:requestedKeyData->data() length:requestedKeyData->byteLength()]);
     1614        [dataRequest respondWithData:nsData.get()];
     1615    }
     1616
     1617    [request finishLoading];
     1618}
     1619#endif
     1620
    15841621bool MediaPlayerPrivateAVFoundationObjC::shouldWaitForLoadingOfResource(AVAssetResourceLoadingRequest* avRequest)
    15851622{
     
    16091646        m_keyURIToRequestMap.set(keyURI, avRequest);
    16101647        return true;
     1648#if ENABLE(ENCRYPTED_MEDIA_V2)
     1649    } else if (scheme == "clearkey") {
     1650        String keyID = [[[avRequest request] URL] resourceSpecifier];
     1651        StringView keyIDView(keyID);
     1652        CString utf8EncodedKeyId = UTF8Encoding().encode(keyIDView, URLEncodedEntitiesForUnencodables);
     1653
     1654        RefPtr<Uint8Array> initData = Uint8Array::create(utf8EncodedKeyId.length());
     1655        initData->setRange((JSC::Uint8Adaptor::Type*)utf8EncodedKeyId.data(), utf8EncodedKeyId.length(), 0);
     1656
     1657        auto keyData = player()->cachedKeyForKeyId(keyID);
     1658        if (keyData) {
     1659            fulfillRequestWithKeyData(avRequest, keyData.get());
     1660            return false;
     1661        }
     1662
     1663        if (!player()->keyNeeded(initData.get()))
     1664            return false;
     1665
     1666        m_keyURIToRequestMap.set(keyID, avRequest);
     1667        return true;
     1668#endif
    16111669    }
    16121670#endif
     
    22992357{
    23002358    return m_keyURIToRequestMap.take(keyURI);
     2359}
     2360
     2361void MediaPlayerPrivateAVFoundationObjC::keyAdded()
     2362{
     2363    Vector<String> fulfilledKeyIds;
     2364
     2365    for (auto& pair : m_keyURIToRequestMap) {
     2366        const String& keyId = pair.key;
     2367        const RetainPtr<AVAssetResourceLoadingRequest>& request = pair.value;
     2368
     2369        auto keyData = player()->cachedKeyForKeyId(keyId);
     2370        if (!keyData)
     2371            continue;
     2372
     2373        fulfillRequestWithKeyData(request.get(), keyData.get());
     2374        fulfilledKeyIds.append(keyId);
     2375    }
     2376
     2377    for (auto& keyId : fulfilledKeyIds)
     2378        m_keyURIToRequestMap.remove(keyId);
    23012379}
    23022380
Note: See TracChangeset for help on using the changeset viewer.