Title: [242720] trunk/Source/WebCore
Revision
242720
Author
jer.no...@apple.com
Date
2019-03-11 11:30:11 -0700 (Mon, 11 Mar 2019)

Log Message

Use AVContentKeySession for "com.apple.fps.2_0" CDM version when AVStreamSession is absent
https://bugs.webkit.org/show_bug.cgi?id=195462
<rdar://problem/48712306>

Reviewed by Eric Carlson.

The difference between "com.apple.fps.2_0" and "3_0" is a protocol difference more than an
implementation difference. In "2_0", the "EME nitialization" data comes in the form of a "content
identifier", while the true initialization data is retrieved through a side channel directly from
the attached element. In "3_0", the "EME initialization data" is the exact initialization data
given by the parser, with no "content identifier" at all.

In the original implementation, the "2_0" used AVStreamSession, and "3_0" used AVContentKeySession,
but in the absense of AVStreamSession, those protocol differences are minor and can be implemented
using AVContentKeySession.

Changes:

- Add a new helper struct in CDMPrivateMediaSourceAVFObjC that represents the parsed parameters
  of the CDM string.
- Add an "initData()" accessor to SourceBufferPrivateAVFObjC so that the "2_0" path can implement
  the side channel access to the necessary initialization data.
- Refactor some of the SPI code to not re-declare unnecessary APIs.
- In CDMSessionAVContentKeySession::generateKeyRequest(), this function can never be called twice
  so it is a logical impossibility to have a certificate at this point. Remove all this if() code.

* Modules/encryptedmedia/legacy/LegacyCDM.cpp:
* platform/graphics/avfoundation/CDMPrivateMediaSourceAVFObjC.h:
* platform/graphics/avfoundation/CDMPrivateMediaSourceAVFObjC.mm:
(WebCore::CDMPrivateMediaSourceAVFObjC::parseKeySystem):
(WebCore::queryDecoderAvailability):
(WebCore::CDMPrivateMediaSourceAVFObjC::supportsKeySystem):
(WebCore::CDMPrivateMediaSourceAVFObjC::createSession):
(WebCore::validKeySystemRE): Deleted.
* platform/graphics/avfoundation/objc/CDMSessionAVContentKeySession.h:
* platform/graphics/avfoundation/objc/CDMSessionAVContentKeySession.mm:
(WebCore::CDMSessionAVContentKeySession::CDMSessionAVContentKeySession):
(WebCore::CDMSessionAVContentKeySession::generateKeyRequest):
(WebCore::CDMSessionAVContentKeySession::update):
(WebCore::CDMSessionAVContentKeySession::addParser):
(WebCore::CDMSessionAVContentKeySession::removeParser):
(WebCore::CDMSessionAVContentKeySession::contentKeySession):
* platform/graphics/avfoundation/objc/CDMSessionAVStreamSession.h:
* platform/graphics/avfoundation/objc/CDMSessionAVStreamSession.mm:
(WebCore::CDMSessionAVStreamSession::CDMSessionAVStreamSession):
* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h:
* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::setCDMSession):
* platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.h:
* platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm:
(WebCore::SourceBufferPrivateAVFObjC::didProvideContentKeyRequestInitializationDataForTrackID):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (242719 => 242720)


--- trunk/Source/WebCore/ChangeLog	2019-03-11 18:22:02 UTC (rev 242719)
+++ trunk/Source/WebCore/ChangeLog	2019-03-11 18:30:11 UTC (rev 242720)
@@ -1,3 +1,57 @@
+2019-03-11  Jer Noble  <jer.no...@apple.com>
+
+        Use AVContentKeySession for "com.apple.fps.2_0" CDM version when AVStreamSession is absent
+        https://bugs.webkit.org/show_bug.cgi?id=195462
+        <rdar://problem/48712306>
+
+        Reviewed by Eric Carlson.
+
+        The difference between "com.apple.fps.2_0" and "3_0" is a protocol difference more than an
+        implementation difference. In "2_0", the "EME nitialization" data comes in the form of a "content
+        identifier", while the true initialization data is retrieved through a side channel directly from
+        the attached element. In "3_0", the "EME initialization data" is the exact initialization data
+        given by the parser, with no "content identifier" at all.
+
+        In the original implementation, the "2_0" used AVStreamSession, and "3_0" used AVContentKeySession,
+        but in the absense of AVStreamSession, those protocol differences are minor and can be implemented
+        using AVContentKeySession.
+
+        Changes:
+
+        - Add a new helper struct in CDMPrivateMediaSourceAVFObjC that represents the parsed parameters
+          of the CDM string.
+        - Add an "initData()" accessor to SourceBufferPrivateAVFObjC so that the "2_0" path can implement
+          the side channel access to the necessary initialization data.
+        - Refactor some of the SPI code to not re-declare unnecessary APIs.
+        - In CDMSessionAVContentKeySession::generateKeyRequest(), this function can never be called twice
+          so it is a logical impossibility to have a certificate at this point. Remove all this if() code.
+
+        * Modules/encryptedmedia/legacy/LegacyCDM.cpp:
+        * platform/graphics/avfoundation/CDMPrivateMediaSourceAVFObjC.h:
+        * platform/graphics/avfoundation/CDMPrivateMediaSourceAVFObjC.mm:
+        (WebCore::CDMPrivateMediaSourceAVFObjC::parseKeySystem):
+        (WebCore::queryDecoderAvailability):
+        (WebCore::CDMPrivateMediaSourceAVFObjC::supportsKeySystem):
+        (WebCore::CDMPrivateMediaSourceAVFObjC::createSession):
+        (WebCore::validKeySystemRE): Deleted.
+        * platform/graphics/avfoundation/objc/CDMSessionAVContentKeySession.h:
+        * platform/graphics/avfoundation/objc/CDMSessionAVContentKeySession.mm:
+        (WebCore::CDMSessionAVContentKeySession::CDMSessionAVContentKeySession):
+        (WebCore::CDMSessionAVContentKeySession::generateKeyRequest):
+        (WebCore::CDMSessionAVContentKeySession::update):
+        (WebCore::CDMSessionAVContentKeySession::addParser):
+        (WebCore::CDMSessionAVContentKeySession::removeParser):
+        (WebCore::CDMSessionAVContentKeySession::contentKeySession):
+        * platform/graphics/avfoundation/objc/CDMSessionAVStreamSession.h:
+        * platform/graphics/avfoundation/objc/CDMSessionAVStreamSession.mm:
+        (WebCore::CDMSessionAVStreamSession::CDMSessionAVStreamSession):
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h:
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
+        (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::setCDMSession):
+        * platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.h:
+        * platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm:
+        (WebCore::SourceBufferPrivateAVFObjC::didProvideContentKeyRequestInitializationDataForTrackID):
+
 2019-03-11  Ryan Haddad  <ryanhad...@apple.com>
 
         Unreviewed, rolling out r242688, r242643, r242624.

Modified: trunk/Source/WebCore/Modules/encryptedmedia/legacy/LegacyCDM.cpp (242719 => 242720)


--- trunk/Source/WebCore/Modules/encryptedmedia/legacy/LegacyCDM.cpp	2019-03-11 18:22:02 UTC (rev 242719)
+++ trunk/Source/WebCore/Modules/encryptedmedia/legacy/LegacyCDM.cpp	2019-03-11 18:30:11 UTC (rev 242720)
@@ -37,7 +37,7 @@
 #include <wtf/NeverDestroyed.h>
 #include <wtf/text/WTFString.h>
 
-#if PLATFORM(MAC) && ENABLE(MEDIA_SOURCE)
+#if (HAVE(AVCONTENTKEYSESSION) || HAVE(AVSTREAMSESSION)) && ENABLE(MEDIA_SOURCE)
 #include "CDMPrivateMediaSourceAVFObjC.h"
 #endif
 
@@ -68,7 +68,7 @@
         new CDMFactory([](LegacyCDM* cdm) { return std::make_unique<CDMPrivateMediaPlayer>(cdm); },
             CDMPrivateMediaPlayer::supportsKeySystem, CDMPrivateMediaPlayer::supportsKeySystemAndMimeType),
 
-#if PLATFORM(MAC) && ENABLE(MEDIA_SOURCE)
+#if (HAVE(AVCONTENTKEYSESSION) || HAVE(AVSTREAMSESSION)) && ENABLE(MEDIA_SOURCE)
         new CDMFactory([](LegacyCDM* cdm) { return std::make_unique<CDMPrivateMediaSourceAVFObjC>(cdm); },
             CDMPrivateMediaSourceAVFObjC::supportsKeySystem, CDMPrivateMediaSourceAVFObjC::supportsKeySystemAndMimeType),
 #endif

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/CDMPrivateMediaSourceAVFObjC.h (242719 => 242720)


--- trunk/Source/WebCore/platform/graphics/avfoundation/CDMPrivateMediaSourceAVFObjC.h	2019-03-11 18:22:02 UTC (rev 242719)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/CDMPrivateMediaSourceAVFObjC.h	2019-03-11 18:30:11 UTC (rev 242720)
@@ -52,8 +52,13 @@
     LegacyCDM* cdm() const { return m_cdm; }
 
     void invalidateSession(CDMSessionMediaSourceAVFObjC*);
-
 protected:
+    struct KeySystemParameters {
+        int version;
+        Vector<int> protocols;
+    };
+    static Optional<KeySystemParameters> parseKeySystem(const String& keySystem);
+    
     LegacyCDM* m_cdm;
     Vector<CDMSessionMediaSourceAVFObjC*> m_sessions;
 };

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/CDMPrivateMediaSourceAVFObjC.mm (242719 => 242720)


--- trunk/Source/WebCore/platform/graphics/avfoundation/CDMPrivateMediaSourceAVFObjC.mm	2019-03-11 18:22:02 UTC (rev 242719)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/CDMPrivateMediaSourceAVFObjC.mm	2019-03-11 18:30:11 UTC (rev 242720)
@@ -43,10 +43,25 @@
 
 namespace WebCore {
 
-static RegularExpression& validKeySystemRE()
+auto CDMPrivateMediaSourceAVFObjC::parseKeySystem(const String& keySystem) -> Optional<KeySystemParameters>
 {
     static NeverDestroyed<RegularExpression> keySystemRE("^com\\.apple\\.fps\\.[23]_\\d+(?:,\\d+)*$", JSC::Yarr::TextCaseInsensitive);
-    return keySystemRE;
+
+    if (keySystem.isEmpty())
+        return WTF::nullopt;
+    
+    if (keySystemRE.get().match(keySystem) < 0)
+        return WTF::nullopt;
+    
+    StringView keySystemView { keySystem };
+
+    int cdmVersion = keySystemView.substring(14, 1).toInt();
+    
+    Vector<int> protocolVersions;
+    for (StringView protocolVersionString : keySystemView.substring(16).split(','))
+        protocolVersions.append(protocolVersionString.toInt());
+    
+    return {{ cdmVersion, WTFMove(protocolVersions) }};
 }
 
 CDMPrivateMediaSourceAVFObjC::~CDMPrivateMediaSourceAVFObjC()
@@ -58,7 +73,11 @@
 static bool queryDecoderAvailability()
 {
     if (!canLoad_VideoToolbox_VTGetGVADecoderAvailability())
+#if HAVE(AVSTREAMSESSION)
         return false;
+#else
+        return true;
+#endif
     uint32_t totalInstanceCount = 0;
     OSStatus status = VTGetGVADecoderAvailability(&totalInstanceCount, nullptr);
     return status == noErr && totalInstanceCount;
@@ -69,10 +88,11 @@
     if (!queryDecoderAvailability())
         return false;
 
-    if (!keySystem.isEmpty() && validKeySystemRE().match(keySystem) < 0)
+    auto parameters = parseKeySystem(keySystem);
+    if (!parameters)
         return false;
 
-    if (keySystem.substring(14, 1).toInt() == 3 && !CDMSessionAVContentKeySession::isAvailable())
+    if (parameters.value().version == 3 && !CDMSessionAVContentKeySession::isAvailable())
         return false;
 
     return true;
@@ -113,19 +133,24 @@
 std::unique_ptr<LegacyCDMSession> CDMPrivateMediaSourceAVFObjC::createSession(LegacyCDMSessionClient* client)
 {
     String keySystem = m_cdm->keySystem(); // Local copy for StringView usage
-    StringView keySystemStringView { keySystem };
-    ASSERT(validKeySystemRE().match(keySystem) >= 0);
+    auto parameters = parseKeySystem(m_cdm->keySystem());
+    ASSERT(parameters);
+    if (!parameters)
+        return nullptr;
 
-    Vector<int> protocolVersions;
-    for (StringView protocolVersionString : keySystemStringView.substring(16).split(','))
-        protocolVersions.append(protocolVersionString.toInt());
-
     std::unique_ptr<CDMSessionMediaSourceAVFObjC> session;
-    if (keySystemStringView.substring(14, 1).toInt() == 3 && CDMSessionAVContentKeySession::isAvailable())
-        session = std::make_unique<CDMSessionAVContentKeySession>(protocolVersions, *this, client);
+    
+#if HAVE(AVSTREAMSESSION)
+    bool shouldUseAVContentKeySession = parameters.value().version == 3;
+#else
+    bool shouldUseAVContentKeySession = true;
+#endif
+    
+    if (shouldUseAVContentKeySession && CDMSessionAVContentKeySession::isAvailable())
+        session = std::make_unique<CDMSessionAVContentKeySession>(WTFMove(parameters.value().protocols), parameters.value().version, *this, client);
     else
-#if HAVE(AVSTREAMSESSION) && ENABLE(LEGACY_ENCRYPTED_MEDIA)
-        session = std::make_unique<CDMSessionAVStreamSession>(protocolVersions, *this, client);
+#if HAVE(AVSTREAMSESSION)
+        session = std::make_unique<CDMSessionAVStreamSession>(WTFMove(parameters.value().protocols), *this, client);
 #else
         return nullptr;
 #endif

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionAVContentKeySession.h (242719 => 242720)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionAVContentKeySession.h	2019-03-11 18:22:02 UTC (rev 242719)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionAVContentKeySession.h	2019-03-11 18:30:11 UTC (rev 242720)
@@ -43,7 +43,7 @@
 class CDMSessionAVContentKeySession : public CDMSessionMediaSourceAVFObjC {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    CDMSessionAVContentKeySession(const Vector<int>& protocolVersions, CDMPrivateMediaSourceAVFObjC&, LegacyCDMSessionClient*);
+    CDMSessionAVContentKeySession(Vector<int>&& protocolVersions, int cdmVersion, CDMPrivateMediaSourceAVFObjC&, LegacyCDMSessionClient*);
     virtual ~CDMSessionAVContentKeySession();
 
     static bool isAvailable();
@@ -69,9 +69,11 @@
     RetainPtr<AVContentKeySession> m_contentKeySession;
     RetainPtr<WebCDMSessionAVContentKeySessionDelegate> m_contentKeySessionDelegate;
     RetainPtr<AVContentKeyRequest> m_keyRequest;
+    RefPtr<Uint8Array> m_identifier;
     RefPtr<Uint8Array> m_initData;
     RetainPtr<NSData> m_expiredSession;
     Vector<int> m_protocolVersions;
+    int m_cdmVersion;
     int32_t m_protectedTrackID { 1 };
     enum { Normal, KeyRelease } m_mode;
 };

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionAVContentKeySession.mm (242719 => 242720)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionAVContentKeySession.mm	2019-03-11 18:22:02 UTC (rev 242719)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionAVContentKeySession.mm	2019-03-11 18:30:11 UTC (rev 242720)
@@ -38,6 +38,7 @@
 #import <CoreMedia/CMBase.h>
 #import <_javascript_Core/TypedArrayInlines.h>
 #import <objc/objc-runtime.h>
+#import <pal/spi/mac/AVFoundationSPI.h>
 #import <wtf/FileSystem.h>
 #import <wtf/SoftLinking.h>
 
@@ -44,44 +45,27 @@
 SOFT_LINK_FRAMEWORK_OPTIONAL(AVFoundation)
 SOFT_LINK_CLASS(AVFoundation, AVStreamDataParser);
 SOFT_LINK_CLASS_OPTIONAL(AVFoundation, AVContentKeySession);
+SOFT_LINK_CLASS_OPTIONAL(AVFoundation, AVContentKeyResponse);
 SOFT_LINK_CONSTANT_MAY_FAIL(AVFoundation, AVContentKeyRequestProtocolVersionsKey, NSString *)
 SOFT_LINK_CONSTANT_MAY_FAIL(AVFoundation, AVContentKeySystemFairPlayStreaming, NSString *)
 
 typedef NSString *AVContentKeySystem;
 
-@interface AVContentKeySession : NSObject
-+ (instancetype)contentKeySessionWithKeySystem:(AVContentKeySystem)keySystem;
+@interface AVContentKeySession (WebCorePrivate)
 - (instancetype)initWithStorageDirectoryAtURL:(NSURL *)storageURL;
 @property (assign) id delegate;
 - (void)addStreamDataParser:(AVStreamDataParser *)streamDataParser;
 - (void)removeStreamDataParser:(AVStreamDataParser *)streamDataParser;
-@property (readonly) NSArray *streamDataParsers;
-- (void)expire;
-@property (readonly) NSData *contentProtectionSessionIdentifier;
 - (void)processContentKeyRequestInitializationData:(NSData *)initializationData options:(NSDictionary *)options;
-+ (NSArray *)pendingExpiredSessionReportsWithAppIdentifier:(NSData *)appIdentifier storageDirectoryAtURL:(NSURL *)storageURL;
-+ (void)removePendingExpiredSessionReports:(NSArray *)expiredSessionReports withAppIdentifier:(NSData *)appIdentifier storageDirectoryAtURL:(NSURL *)storageURL;
 @end
 
-typedef NS_ENUM(NSInteger, AVContentKeyRequestStatus) {
-    AVContentKeySessionStatusNoKey,
-    AVContentKeySessionStatusRequestingKey,
-    AVContentKeySessionStatusKeyPresent,
-    AVContentKeySessionStatusExpired,
-    AVContentKeySessionStatusFailed
-};
-
-@interface AVContentKeyRequest : NSObject
-@property (readonly) AVContentKeyRequestStatus status;
-@property (readonly) NSError *error;
-@property (readonly) NSData *initializationData;
+@interface AVContentKeyRequest (WebCorePrivate)
 - (NSData *)contentKeyRequestDataForApp:(NSData *)appIdentifier contentIdentifier:(NSData *)contentIdentifier options:(NSDictionary *)options error:(NSError **)outError;
 - (void)processContentKeyResponseData:(NSData *)contentKeyResponseData;
-- (void)processContentKeyResponseError:(NSError *)error;
 - (void)renewExpiringContentKeyResponseData;
 @end
 
-@interface WebCDMSessionAVContentKeySessionDelegate : NSObject {
+@interface WebCDMSessionAVContentKeySessionDelegate : NSObject<AVContentKeySessionDelegate> {
     WebCore::CDMSessionAVContentKeySession *m_parent;
 }
 - (void)invalidate;
@@ -124,10 +108,11 @@
 
 namespace WebCore {
 
-CDMSessionAVContentKeySession::CDMSessionAVContentKeySession(const Vector<int>& protocolVersions, CDMPrivateMediaSourceAVFObjC& cdm, LegacyCDMSessionClient* client)
+CDMSessionAVContentKeySession::CDMSessionAVContentKeySession(Vector<int>&& protocolVersions, int cdmVersion, CDMPrivateMediaSourceAVFObjC& cdm, LegacyCDMSessionClient* client)
     : CDMSessionMediaSourceAVFObjC(cdm, client)
     , m_contentKeySessionDelegate(adoptNS([[WebCDMSessionAVContentKeySessionDelegate alloc] initWithParent:this]))
-    , m_protocolVersions(protocolVersions)
+    , m_protocolVersions(WTFMove(protocolVersions))
+    , m_cdmVersion(cdmVersion)
     , m_mode(Normal)
 {
 }
@@ -156,27 +141,23 @@
     errorCode = MediaPlayer::NoError;
     systemCode = 0;
 
-    m_initData = initData;
-
     if (equalLettersIgnoringASCIICase(mimeType, "keyrelease")) {
         m_mode = KeyRelease;
+        m_certificate = initData;
         return generateKeyReleaseMessage(errorCode, systemCode);
     }
 
-    if (!m_certificate) {
-        String certificateString("certificate"_s);
-        auto array = Uint8Array::create(certificateString.length());
-        for (unsigned i = 0, length = certificateString.length(); i < length; ++i)
-            array->set(i, certificateString[i]);
-        return WTFMove(array);
-    }
+    if (m_cdmVersion == 2)
+        m_identifier = initData;
+    else
+        m_initData = initData;
 
-    if (!m_keyRequest) {
-        NSData* nsInitData = [NSData dataWithBytes:m_initData->data() length:m_initData->length()];
-        [contentKeySession() processContentKeyRequestInitializationData:nsInitData options:nil];
-    }
-
-    return nullptr;
+    ASSERT(!m_certificate);
+    String certificateString("certificate"_s);
+    auto array = Uint8Array::create(certificateString.length());
+    for (unsigned i = 0, length = certificateString.length(); i < length; ++i)
+        array->set(i, certificateString[i]);
+    return WTFMove(array);
 }
 
 void CDMSessionAVContentKeySession::releaseKeys()
@@ -268,10 +249,34 @@
 
     if (m_mode == KeyRelease)
         return false;
+    
+    if (m_cdmVersion == 2) {
+        // In the com.apple.fps.2_0 communication protocol, the client must first attach the
+        // session to the protected SourceBuffer in order to get access to the initialization
+        // data.
+        RefPtr<SourceBufferPrivateAVFObjC> protectedSourceBuffer;
+        for (auto& sourceBuffer : m_sourceBuffers) {
+            if (sourceBuffer->protectedTrackID() != -1) {
+                protectedSourceBuffer = sourceBuffer;
+                break;
+            }
+        }
 
+        if (!protectedSourceBuffer) {
+            errorCode = MediaPlayer::InvalidPlayerState;
+            return false;
+        }
+        
+        m_initData = protectedSourceBuffer->initData();
+    }
+
     if (!m_keyRequest) {
-        NSData* nsInitData = [NSData dataWithBytes:m_initData->data() length:m_initData->length()];
-        [contentKeySession() processContentKeyRequestInitializationData:nsInitData options:nil];
+        NSData* nsInitData = m_initData ? [NSData dataWithBytes:m_initData->data() length:m_initData->length()] : nil;
+        NSData* nsIdentifier = m_identifier ? [NSData dataWithBytes:m_identifier->data() length:m_identifier->length()] : nil;
+        if ([contentKeySession() respondsToSelector:@selector(processContentKeyRequestWithIdentifier:initializationData:options:)])
+            [contentKeySession() processContentKeyRequestWithIdentifier:nsIdentifier initializationData:nsInitData options:nil];
+        else
+            [contentKeySession() processContentKeyRequestInitializationData:nsInitData options:nil];
     }
 
     if (shouldGenerateKeyRequest) {
@@ -293,7 +298,9 @@
         errorCode = MediaPlayer::NoError;
         systemCode = 0;
         NSError* error = nil;
-        NSData* requestData = [m_keyRequest contentKeyRequestDataForApp:certificateData.get() contentIdentifier:nil options:options.get() error:&error];
+        NSData* nsIdentifier = m_identifier ? [NSData dataWithBytes:m_identifier->data() length:m_identifier->length()] : m_keyRequest.get().identifier;
+
+        NSData* requestData = [m_keyRequest contentKeyRequestDataForApp:certificateData.get() contentIdentifier:nsIdentifier options:options.get() error:&error];
         if (error) {
             errorCode = LegacyCDM::DomainError;
             systemCode = mediaKeyErrorSystemCode(error);
@@ -308,7 +315,11 @@
     errorCode = MediaPlayer::NoError;
     systemCode = 0;
     RetainPtr<NSData> keyData = adoptNS([[NSData alloc] initWithBytes:key->data() length:key->length()]);
-    [m_keyRequest processContentKeyResponseData:keyData.get()];
+    
+    if ([m_keyRequest respondsToSelector:@selector(processContentKeyResponse:)] && [getAVContentKeyResponseClass() respondsToSelector:@selector(contentKeyResponseWithFairPlayStreamingKeyResponseData:)])
+        [m_keyRequest processContentKeyResponse:[getAVContentKeyResponseClass() contentKeyResponseWithFairPlayStreamingKeyResponseData:keyData.get()]];
+    else
+        [m_keyRequest processContentKeyResponseData:keyData.get()];
 
     return true;
 }
@@ -315,18 +326,23 @@
 
 void CDMSessionAVContentKeySession::addParser(AVStreamDataParser* parser)
 {
-    [contentKeySession() addStreamDataParser:parser];
+    if ([contentKeySession() respondsToSelector:@selector(addContentKeyRecipient:)])
+        [contentKeySession() addContentKeyRecipient:parser];
+    else
+        [contentKeySession() addStreamDataParser:parser];
 }
 
 void CDMSessionAVContentKeySession::removeParser(AVStreamDataParser* parser)
 {
-    [contentKeySession() removeStreamDataParser:parser];
+    if ([contentKeySession() respondsToSelector:@selector(removeContentKeyRecipient:)])
+        [contentKeySession() removeContentKeyRecipient:parser];
+    else
+        [contentKeySession() removeStreamDataParser:parser];
 }
 
 RefPtr<Uint8Array> CDMSessionAVContentKeySession::generateKeyReleaseMessage(unsigned short& errorCode, uint32_t& systemCode)
 {
     ASSERT(m_mode == KeyRelease);
-    m_certificate = m_initData;
     RetainPtr<NSData> certificateData = adoptNS([[NSData alloc] initWithBytes:m_certificate->data() length:m_certificate->length()]);
 
     String storagePath = this->storagePath();
@@ -377,7 +393,11 @@
                 return nil;
         }
 
-        m_contentKeySession = adoptNS([allocAVContentKeySessionInstance() initWithStorageDirectoryAtURL:[NSURL fileURLWithPath:storagePath]]);
+        auto url = "" fileURLWithPath:storagePath];
+        if ([getAVContentKeySessionClass() respondsToSelector:@selector(contentKeySessionWithKeySystem:storageDirectoryAtURL:)] && canLoadAVContentKeySystemFairPlayStreaming())
+            m_contentKeySession = [getAVContentKeySessionClass() contentKeySessionWithKeySystem:getAVContentKeySystemFairPlayStreaming() storageDirectoryAtURL:url];
+        else
+            m_contentKeySession = adoptNS([allocAVContentKeySessionInstance() initWithStorageDirectoryAtURL:url]);
     }
 
     m_contentKeySession.get().delegate = m_contentKeySessionDelegate.get();

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionAVStreamSession.h (242719 => 242720)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionAVStreamSession.h	2019-03-11 18:22:02 UTC (rev 242719)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionAVStreamSession.h	2019-03-11 18:30:11 UTC (rev 242720)
@@ -43,7 +43,7 @@
 class CDMSessionAVStreamSession : public CDMSessionMediaSourceAVFObjC, public CanMakeWeakPtr<CDMSessionAVStreamSession> {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    CDMSessionAVStreamSession(const Vector<int>& protocolVersions, CDMPrivateMediaSourceAVFObjC&, LegacyCDMSessionClient*);
+    CDMSessionAVStreamSession(Vector<int>&& protocolVersions, CDMPrivateMediaSourceAVFObjC&, LegacyCDMSessionClient*);
     virtual ~CDMSessionAVStreamSession();
 
     // LegacyCDMSession

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionAVStreamSession.mm (242719 => 242720)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionAVStreamSession.mm	2019-03-11 18:22:02 UTC (rev 242719)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionAVStreamSession.mm	2019-03-11 18:30:11 UTC (rev 242720)
@@ -87,10 +87,10 @@
 
 namespace WebCore {
 
-CDMSessionAVStreamSession::CDMSessionAVStreamSession(const Vector<int>& protocolVersions, CDMPrivateMediaSourceAVFObjC& cdm, LegacyCDMSessionClient* client)
+CDMSessionAVStreamSession::CDMSessionAVStreamSession(Vector<int>&& protocolVersions, CDMPrivateMediaSourceAVFObjC& cdm, LegacyCDMSessionClient* client)
     : CDMSessionMediaSourceAVFObjC(cdm, client)
     , m_dataParserObserver(adoptNS([[WebCDMSessionAVStreamSessionObserver alloc] initWithParent:this]))
-    , m_protocolVersions(protocolVersions)
+    , m_protocolVersions(WTFMove(protocolVersions))
     , m_mode(Normal)
 {
 }

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h (242719 => 242720)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h	2019-03-11 18:22:02 UTC (rev 242719)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h	2019-03-11 18:30:11 UTC (rev 242720)
@@ -115,9 +115,11 @@
     void setTextTrackRepresentation(TextTrackRepresentation*) override;
     void syncTextTrackBounds() override;
     
-#if HAVE(AVSTREAMSESSION) && ENABLE(LEGACY_ENCRYPTED_MEDIA)
+#if ENABLE(LEGACY_ENCRYPTED_MEDIA)
+#if HAVE(AVSTREAMSESSION)
     bool hasStreamSession() { return m_streamSession; }
     AVStreamSession *streamSession();
+#endif
     void setCDMSession(LegacyCDMSession*) override;
     CDMSessionMediaSourceAVFObjC* cdmSession() const { return m_session.get(); }
 #endif

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm (242719 => 242720)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm	2019-03-11 18:22:02 UTC (rev 242719)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm	2019-03-11 18:30:11 UTC (rev 242720)
@@ -933,7 +933,8 @@
     m_sizeChangeObserverWeakPtrFactory.revokeAll();
 }
 
-#if HAVE(AVSTREAMSESSION) && ENABLE(LEGACY_ENCRYPTED_MEDIA)
+#if ENABLE(LEGACY_ENCRYPTED_MEDIA)
+#if HAVE(AVSTREAMSESSION)
 AVStreamSession* MediaPlayerPrivateMediaSourceAVFObjC::streamSession()
 {
     if (!getAVStreamSessionClass() || ![getAVStreamSessionClass() instancesRespondToSelector:@selector(initWithStorageDirectoryAtURL:)])
@@ -954,6 +955,7 @@
     }
     return m_streamSession.get();
 }
+#endif
 
 void MediaPlayerPrivateMediaSourceAVFObjC::setCDMSession(LegacyCDMSession* session)
 {
@@ -964,12 +966,15 @@
 
     m_session = makeWeakPtr(toCDMSessionMediaSourceAVFObjC(session));
 
+#if HAVE(AVSTREAMSESSION)
     if (CDMSessionAVStreamSession* cdmStreamSession = toCDMSessionAVStreamSession(m_session.get()))
         cdmStreamSession->setStreamSession(streamSession());
+#endif
+
     for (auto& sourceBuffer : m_mediaSourcePrivate->sourceBuffers())
         sourceBuffer->setCDMSession(m_session.get());
 }
-#endif // HAVE(AVSTREAMSESSION) && ENABLE(LEGACY_ENCRYPTED_MEDIA)
+#endif // ENABLE(LEGACY_ENCRYPTED_MEDIA)
 
 #if ENABLE(LEGACY_ENCRYPTED_MEDIA) || ENABLE(ENCRYPTED_MEDIA)
 void MediaPlayerPrivateMediaSourceAVFObjC::keyNeeded(Uint8Array* initData)

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.h (242719 => 242720)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.h	2019-03-11 18:22:02 UTC (rev 242719)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.h	2019-03-11 18:30:11 UTC (rev 242720)
@@ -133,6 +133,10 @@
     void setDecompressionSession(WebCoreDecompressionSession*);
 
     void bufferWasConsumed();
+    
+#if ENABLE(LEGACY_ENCRYPTED_MEDIA)
+    Uint8Array* initData() { return m_initData.get(); }
+#endif
 
 #if !RELEASE_LOG_DISABLED
     const Logger& logger() const final { return m_logger.get(); }
@@ -196,6 +200,7 @@
     MediaSourcePrivateAVFObjC* m_mediaSource;
     SourceBufferPrivateClient* m_client { nullptr };
 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
+    RefPtr<Uint8Array> m_initData;
     WeakPtr<CDMSessionMediaSourceAVFObjC> m_session { nullptr };
 #endif
 #if ENABLE(ENCRYPTED_MEDIA) && HAVE(AVCONTENTKEYSESSION)

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm (242719 => 242720)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm	2019-03-11 18:22:02 UTC (rev 242719)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm	2019-03-11 18:30:11 UTC (rev 242720)
@@ -661,13 +661,13 @@
     if (!m_mediaSource)
         return;
 
-#if HAVE(AVSTREAMSESSION) && ENABLE(LEGACY_ENCRYPTED_MEDIA)
+#if HAVE(AVCONTENTKEYSESSION) && ENABLE(LEGACY_ENCRYPTED_MEDIA)
     ALWAYS_LOG(LOGIDENTIFIER, "track = ", trackID);
 
     m_protectedTrackID = trackID;
-    auto initDataArray = Uint8Array::create([initData length]);
-    [initData getBytes:initDataArray->data() length:initDataArray->length()];
-    m_mediaSource->sourceBufferKeyNeeded(this, initDataArray.ptr());
+    m_initData = Uint8Array::create([initData length]);
+    [initData getBytes:m_initData->data() length:m_initData->length()];
+    m_mediaSource->sourceBufferKeyNeeded(this, m_initData.get());
     if (auto session = m_mediaSource->player()->cdmSession()) {
         session->addParser(m_parser.get());
         hasSessionSemaphore->signal();
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to