Title: [175000] trunk/Source/WebCore
Revision
175000
Author
[email protected]
Date
2014-10-21 16:06:59 -0700 (Tue, 21 Oct 2014)

Log Message

[EME][Mac] Update to match new AVStreamSession API and requirements.
https://bugs.webkit.org/show_bug.cgi?id=137923

Reviewed by Eric Carlson.

The session identifier has moved from AVStreamDataParser to -[AVStreamSession contentProtectionSessionIdentifier]
and the property is no longer KVObservable. A new notification key has been added in place of KVO.

Additionally, the requirements for using AVStreamDataParser with AVStreamSession have changed. It is now
required that AVStreamDataParsers be added to an AVStreamSession before the
-streamSession:didProvideContentKeyRequestInitializationData:forTrackID delegate method is called. A
-streamParserWillProvideContentKeyRequestInitializationData:forTrackID delegate has been added, and
an AVStreamSession must be created and the AVStreamDataParser added to it during the scope of that delegate
method.

To facilitate this, the MediaPlayerPrivateMediaSourceAVFObjC object will lazily create and own a AVStreamSession
object when requested. The SourceBufferPrivateAVFObjC object will listen for the -willProvide delegate call
and will add its AVStreamDataParser to that AVStreamSession when called.

The CDMSessionMediaSourceAVFObjC object is no longer responsible for creating the AVStreamSession, and because
the session identifier has moved from many AVStreamDataParsers to a single AVStreamSession, the
CDMSessionMediaSourceAVFObjCObserver class can become much simpler, as it only has to observe a single object.

* platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.h:
* platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.mm:
(-[CDMSessionMediaSourceAVFObjCObserver dealloc]): Deleted.
(-[CDMSessionMediaSourceAVFObjCObserver beginObserving:]): Deleted.
(-[CDMSessionMediaSourceAVFObjCObserver stopObserving:]): Deleted.
(-[CDMSessionMediaSourceAVFObjCObserver invalidate]): Deleted.
(-[CDMSessionMediaSourceAVFObjCObserver observeValueForKeyPath:ofObject:change:context:]): Deleted.
(-[CDMSessionMediaSourceAVFObjCObserver contentProtectionSessionIdentifierChanged:]): Added.
(WebCore::CDMSessionMediaSourceAVFObjC::~CDMSessionMediaSourceAVFObjC): Call setStreamSession(nullptr).
(WebCore::CDMSessionMediaSourceAVFObjC::releaseKeys): The sessionId is now a value in the dictionary, not the key.
(WebCore::CDMSessionMediaSourceAVFObjC::update): No longer create an AVStreamSession.
(WebCore::CDMSessionMediaSourceAVFObjC::setStreamSession): Add and remove observers as appropriate.
(WebCore::CDMSessionMediaSourceAVFObjC::addSourceBuffer): No longer add or remove parsers from AVStreamSessions.
(WebCore::CDMSessionMediaSourceAVFObjC::removeSourceBuffer): Ditto.
* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h:
* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::hasStreamSession): Simple getter.
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::streamSession): Lazy initializing getter.
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::setCDMSession): Call setStreamSession().
* platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.h:
* platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm:
(-[WebAVStreamDataParserListener streamParserWillProvideContentKeyRequestInitializationData:forTrackID:]): Synchronously pass to SourceBufferPrivateAVFObjC.
(WebCore::SourceBufferPrivateAVFObjC::willProvideContentKeyRequestInitializationDataForTrackID): Add the parser to an AVStreamSession.
(WebCore::SourceBufferPrivateAVFObjC::didProvideContentKeyRequestInitializationDataForTrackID): Check the trackId.
* platform/mac/SoftLinking.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (174999 => 175000)


--- trunk/Source/WebCore/ChangeLog	2014-10-21 21:37:05 UTC (rev 174999)
+++ trunk/Source/WebCore/ChangeLog	2014-10-21 23:06:59 UTC (rev 175000)
@@ -1,3 +1,54 @@
+2014-10-21  Jer Noble  <[email protected]>
+
+        [EME][Mac] Update to match new AVStreamSession API and requirements.
+        https://bugs.webkit.org/show_bug.cgi?id=137923
+
+        Reviewed by Eric Carlson.
+
+        The session identifier has moved from AVStreamDataParser to -[AVStreamSession contentProtectionSessionIdentifier]
+        and the property is no longer KVObservable. A new notification key has been added in place of KVO.
+
+        Additionally, the requirements for using AVStreamDataParser with AVStreamSession have changed. It is now
+        required that AVStreamDataParsers be added to an AVStreamSession before the 
+        -streamSession:didProvideContentKeyRequestInitializationData:forTrackID delegate method is called. A
+        -streamParserWillProvideContentKeyRequestInitializationData:forTrackID delegate has been added, and
+        an AVStreamSession must be created and the AVStreamDataParser added to it during the scope of that delegate
+        method.
+
+        To facilitate this, the MediaPlayerPrivateMediaSourceAVFObjC object will lazily create and own a AVStreamSession
+        object when requested. The SourceBufferPrivateAVFObjC object will listen for the -willProvide delegate call
+        and will add its AVStreamDataParser to that AVStreamSession when called.
+
+        The CDMSessionMediaSourceAVFObjC object is no longer responsible for creating the AVStreamSession, and because
+        the session identifier has moved from many AVStreamDataParsers to a single AVStreamSession, the
+        CDMSessionMediaSourceAVFObjCObserver class can become much simpler, as it only has to observe a single object.
+
+        * platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.h:
+        * platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.mm:
+        (-[CDMSessionMediaSourceAVFObjCObserver dealloc]): Deleted.
+        (-[CDMSessionMediaSourceAVFObjCObserver beginObserving:]): Deleted.
+        (-[CDMSessionMediaSourceAVFObjCObserver stopObserving:]): Deleted.
+        (-[CDMSessionMediaSourceAVFObjCObserver invalidate]): Deleted.
+        (-[CDMSessionMediaSourceAVFObjCObserver observeValueForKeyPath:ofObject:change:context:]): Deleted.
+        (-[CDMSessionMediaSourceAVFObjCObserver contentProtectionSessionIdentifierChanged:]): Added.
+        (WebCore::CDMSessionMediaSourceAVFObjC::~CDMSessionMediaSourceAVFObjC): Call setStreamSession(nullptr).
+        (WebCore::CDMSessionMediaSourceAVFObjC::releaseKeys): The sessionId is now a value in the dictionary, not the key.
+        (WebCore::CDMSessionMediaSourceAVFObjC::update): No longer create an AVStreamSession.
+        (WebCore::CDMSessionMediaSourceAVFObjC::setStreamSession): Add and remove observers as appropriate.
+        (WebCore::CDMSessionMediaSourceAVFObjC::addSourceBuffer): No longer add or remove parsers from AVStreamSessions.
+        (WebCore::CDMSessionMediaSourceAVFObjC::removeSourceBuffer): Ditto.
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h:
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
+        (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::hasStreamSession): Simple getter.
+        (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::streamSession): Lazy initializing getter.
+        (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::setCDMSession): Call setStreamSession().
+        * platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.h:
+        * platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm:
+        (-[WebAVStreamDataParserListener streamParserWillProvideContentKeyRequestInitializationData:forTrackID:]): Synchronously pass to SourceBufferPrivateAVFObjC.
+        (WebCore::SourceBufferPrivateAVFObjC::willProvideContentKeyRequestInitializationDataForTrackID): Add the parser to an AVStreamSession.
+        (WebCore::SourceBufferPrivateAVFObjC::didProvideContentKeyRequestInitializationDataForTrackID): Check the trackId.
+        * platform/mac/SoftLinking.h:
+
 2014-10-21  Jaehun Lim  <[email protected]>
 
         'true' isn't a valid value for justify-self

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.h (174999 => 175000)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.h	2014-10-21 21:37:05 UTC (rev 174999)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.h	2014-10-21 23:06:59 UTC (rev 175000)
@@ -53,6 +53,8 @@
     virtual void layerDidReceiveError(AVSampleBufferDisplayLayer *, NSError *);
     virtual void rendererDidReceiveError(AVSampleBufferAudioRenderer *, NSError *);
 
+    void setStreamSession(AVStreamSession *);
+
     void addSourceBuffer(SourceBufferPrivateAVFObjC*);
     void removeSourceBuffer(SourceBufferPrivateAVFObjC*);
 

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.mm (174999 => 175000)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.mm	2014-10-21 21:37:05 UTC (rev 174999)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.mm	2014-10-21 23:06:59 UTC (rev 175000)
@@ -45,27 +45,27 @@
 SOFT_LINK_FRAMEWORK_OPTIONAL(AVFoundation)
 SOFT_LINK_CLASS(AVFoundation, AVStreamDataParser);
 SOFT_LINK_CLASS_OPTIONAL(AVFoundation, AVStreamSession);
+SOFT_LINK_CONSTANT_MAY_FAIL(AVFoundation, AVStreamSessionContentProtectionSessionIdentifierChangedNotification, NSString *);
 
 @interface AVStreamDataParser : NSObject
 - (void)processContentKeyResponseData:(NSData *)contentKeyResponseData forTrackID:(CMPersistentTrackID)trackID;
 - (void)processContentKeyResponseError:(NSError *)error forTrackID:(CMPersistentTrackID)trackID;
 - (void)renewExpiringContentKeyResponseDataForTrackID:(CMPersistentTrackID)trackID;
 - (NSData *)streamingContentKeyRequestDataForApp:(NSData *)appIdentifier contentIdentifier:(NSData *)contentIdentifier trackID:(CMPersistentTrackID)trackID options:(NSDictionary *)options error:(NSError **)outError;
-- (NSData *)sessionIdentifier;
 @end
 
 @interface AVStreamSession : NSObject
-- (instancetype)initWithAppIdentifier:(NSData *)appIdentifier storageDirectoryAtURL:(NSURL *)storageURL error:(NSError **)outError;
+- (BOOL)setStorageDirectoryAtURL:(NSURL *)storageURL appIdentifier:(NSData *)appIdentifier error:(NSError **)outError;
 - (void)addStreamDataParser:(AVStreamDataParser *)streamDataParser;
 - (void)removeStreamDataParser:(AVStreamDataParser *)streamDataParser;
 - (void)expire;
+- (NSData *)contentProtectionSessionIdentifier;
 + (NSArray *)pendingExpiredSessionReportsWithAppIdentifier:(NSData *)appIdentifier;
 + (void)removePendingExpiredSessionReports:(NSArray *)expiredSessionReports withAppIdentifier:(NSData *)appIdentifier;
 @end
 
 @interface CDMSessionMediaSourceAVFObjCObserver : NSObject {
     WebCore::CDMSessionMediaSourceAVFObjC *m_parent;
-    HashSet<RetainPtr<AVStreamDataParser>> m_parsers;
 }
 @end
 
@@ -77,59 +77,20 @@
     return self;
 }
 
-- (void)dealloc
+- (void)contentProtectionSessionIdentifierChanged:(NSNotification *)notification
 {
-    [self invalidate];
-    [super dealloc];
-}
+    AVStreamSession* streamSession = (AVStreamSession*)[notification object];
 
-- (void)beginObserving:(AVStreamDataParser *)parser
-{
-    ASSERT(!m_parsers.contains(parser));
-    m_parsers.add(parser);
-    if ([parser respondsToSelector:@selector(sessionIdentifier)])
-        [parser addObserver:self forKeyPath:@"sessionIdentifier" options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionInitial) context:nullptr];
-}
+    NSData* identifier = [streamSession contentProtectionSessionIdentifier];
+    RetainPtr<NSString> sessionIdentifierString = identifier ? adoptNS([[NSString alloc] initWithData:identifier encoding:NSUTF8StringEncoding]) : nil;
 
-- (void)stopObserving:(AVStreamDataParser *)parser
-{
-    ASSERT(m_parsers.contains(parser));
-    m_parsers.remove(parser);
-    if ([parser respondsToSelector:@selector(sessionIdentifier)])
-        [parser removeObserver:self forKeyPath:@"sessionIdentifier" context:nullptr];
+    if (m_parent)
+        m_parent->setSessionId(sessionIdentifierString.get());
 }
-
-- (void)invalidate
-{
-    m_parent = nullptr;
-    for (auto& parser : m_parsers) {
-        if ([parser respondsToSelector:@selector(sessionIdentifier)])
-            [parser removeObserver:self forKeyPath:@"sessionIdentifier" context:nullptr];
-    }
-    m_parsers.clear();
-}
-
-- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void*)context
-{
-    UNUSED_PARAM(object);
-    UNUSED_PARAM(change);
-    UNUSED_PARAM(context);
-
-    if ([keyPath isEqual:@"sessionIdentifier"]) {
-        NSData* identifier = [change valueForKey:NSKeyValueChangeNewKey];
-        if ([identifier isKindOfClass:[NSNull class]])
-            return;
-
-        RetainPtr<NSString> sessionIdentifierString = adoptNS([[NSString alloc] initWithData:identifier encoding:(NSUTF8StringEncoding)]);
-        if (m_parent)
-            m_parent->setSessionId(sessionIdentifierString.get());
-        return;
-    }
-
-    ASSERT_NOT_REACHED();
-}
 @end
 
+static const NSString *PlaybackSessionIdKey = @"PlaybackSessionID";
+
 namespace WebCore {
 
 CDMSessionMediaSourceAVFObjC::CDMSessionMediaSourceAVFObjC()
@@ -144,12 +105,9 @@
     for (auto& sourceBuffer : m_sourceBuffers) {
         if (m_streamSession)
             [m_streamSession removeStreamDataParser:sourceBuffer->parser()];
-
-        [sourceBuffer->parser() removeObserver:m_dataParserObserver.get() forKeyPath:@"sessionIdentifier" context:nullptr];
     }
 
-    m_streamSession = nil;
-    [m_dataParserObserver invalidate];
+    setStreamSession(nullptr);
 }
 
 PassRefPtr<Uint8Array> CDMSessionMediaSourceAVFObjC::generateKeyRequest(const String& mimeType, Uint8Array* initData, String& destinationURL, unsigned short& errorCode, unsigned long& systemCode)
@@ -187,7 +145,12 @@
         NSArray* expiredSessions = [getAVStreamSessionClass() pendingExpiredSessionReportsWithAppIdentifier:certificateData.get()];
         for (NSData* expiredSessionData in expiredSessions) {
             NSDictionary *expiredSession = [NSPropertyListSerialization propertyListWithData:expiredSessionData options:kCFPropertyListImmutable format:nullptr error:nullptr];
-            if ([expiredSession objectForKey:m_sessionId]) {
+            NSString *playbackSessionIdValue = (NSString *)[expiredSession objectForKey:PlaybackSessionIdKey];
+            if (![playbackSessionIdValue isKindOfClass:[NSString class]])
+                continue;
+
+            if (m_sessionId == String(playbackSessionIdValue)) {
+                LOG(Media, "CDMSessionMediaSourceAVFObjC::releaseKeys(%p) - found session, sending expiration message");
                 m_expiredSession = expiredSessionData;
                 m_client->sendMessage(Uint8Array::create(static_cast<const uint8_t*>([m_expiredSession bytes]), [m_expiredSession length]).get(), emptyString());
                 break;
@@ -241,6 +204,8 @@
     }
 
     if (isEqual(key, "acknowledged")) {
+        LOG(Media, "CDMSessionMediaSourceAVFObjC::update(%p) - acknowleding secure stop message", this);
+
         if (!m_expiredSession) {
             errorCode = MediaPlayer::InvalidPlayerState;
             return false;
@@ -249,6 +214,7 @@
         RetainPtr<NSData> certificateData = adoptNS([[NSData alloc] initWithBytes:m_certificate->data() length:m_certificate->length()]);
         [getAVStreamSessionClass() removePendingExpiredSessionReports:@[m_expiredSession.get()] withAppIdentifier:certificateData.get()];
         m_expiredSession = nullptr;
+        return true;
     }
 
     RefPtr<SourceBufferPrivateAVFObjC> protectedSourceBuffer;
@@ -261,8 +227,8 @@
 
     if (shouldGenerateKeyRequest) {
         RetainPtr<NSData> certificateData = adoptNS([[NSData alloc] initWithBytes:m_certificate->data() length:m_certificate->length()]);
-        if (getAVStreamSessionClass() && [getAVStreamSessionClass() instancesRespondToSelector:@selector(initWithAppIdentifier:storageDirectoryAtURL:error:)]) {
-            m_streamSession = adoptNS([[getAVStreamSessionClass() alloc] initWithAppIdentifier:certificateData.get() storageDirectoryAtURL:[NSURL fileURLWithPath:sessionStorageDirectory()] error:nil]);
+        if (m_streamSession && [m_streamSession respondsToSelector:@selector(setStorageDirectoryAtURL:storageURL:appIdentifier:error:)]) {
+            [m_streamSession setStorageDirectoryAtURL:[NSURL fileURLWithPath:sessionStorageDirectory()] appIdentifier:certificateData.get() error:nil];
             for (auto& sourceBuffer : m_sourceBuffers)
                 [m_streamSession addStreamDataParser:sourceBuffer->parser()];
             LOG(Media, "CDMSessionMediaSourceAVFObjC::update(%p) - created stream session %p", this, m_streamSession.get());
@@ -279,7 +245,7 @@
         NSError* error = nil;
         RetainPtr<NSData> request = [protectedSourceBuffer->parser() streamingContentKeyRequestDataForApp:certificateData.get() contentIdentifier:initData.get() trackID:protectedSourceBuffer->protectedTrackID() options:nil error:&error];
 
-        if (![protectedSourceBuffer->parser() respondsToSelector:@selector(sessionIdentifier)])
+        if (![protectedSourceBuffer->parser() respondsToSelector:@selector(contentProtectionSessionIdentifier)])
             m_sessionId = createCanonicalUUIDString();
 
         if (error) {
@@ -320,6 +286,24 @@
     m_client->sendError(CDMSessionClient::MediaKeyErrorDomain, std::abs([error code]));
 }
 
+void CDMSessionMediaSourceAVFObjC::setStreamSession(AVStreamSession *streamSession)
+{
+    if (m_streamSession && canLoadAVStreamSessionContentProtectionSessionIdentifierChangedNotification())
+        [[NSNotificationCenter defaultCenter] removeObserver:m_dataParserObserver.get() name:getAVStreamSessionContentProtectionSessionIdentifierChangedNotification() object:m_streamSession.get()];
+
+    m_streamSession = streamSession;
+
+    if (!m_streamSession)
+        return;
+
+    if (canLoadAVStreamSessionContentProtectionSessionIdentifierChangedNotification())
+        [[NSNotificationCenter defaultCenter] addObserver:m_dataParserObserver.get() selector:@selector(contentProtectionSessionIdentifierChanged:) name:getAVStreamSessionContentProtectionSessionIdentifierChangedNotification() object:m_streamSession.get()];
+
+    NSData* identifier = [streamSession contentProtectionSessionIdentifier];
+    RetainPtr<NSString> sessionIdentifierString = identifier ? adoptNS([[NSString alloc] initWithData:identifier encoding:(NSUTF8StringEncoding)]) : nil;
+    setSessionId(sessionIdentifierString.get());
+}
+
 void CDMSessionMediaSourceAVFObjC::addSourceBuffer(SourceBufferPrivateAVFObjC* sourceBuffer)
 {
     ASSERT(!m_sourceBuffers.contains(sourceBuffer));
@@ -327,11 +311,6 @@
 
     m_sourceBuffers.append(sourceBuffer);
     sourceBuffer->registerForErrorNotifications(this);
-
-    if (m_streamSession)
-        [m_streamSession addStreamDataParser:sourceBuffer->parser()];
-
-    [m_dataParserObserver beginObserving:sourceBuffer->parser()];
 }
 
 void CDMSessionMediaSourceAVFObjC::removeSourceBuffer(SourceBufferPrivateAVFObjC* sourceBuffer)
@@ -344,8 +323,6 @@
 
     sourceBuffer->unregisterForErrorNotifications(this);
     m_sourceBuffers.remove(m_sourceBuffers.find(sourceBuffer));
-
-    [m_dataParserObserver stopObserving:sourceBuffer->parser()];
 }
 
 PassRefPtr<Uint8Array> CDMSessionMediaSourceAVFObjC::generateKeyReleaseMessage(unsigned short& errorCode, unsigned long& systemCode)

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


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h	2014-10-21 21:37:05 UTC (rev 174999)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h	2014-10-21 23:06:59 UTC (rev 175000)
@@ -38,6 +38,7 @@
 OBJC_CLASS AVSampleBufferAudioRenderer;
 OBJC_CLASS AVSampleBufferDisplayLayer;
 OBJC_CLASS AVSampleBufferRenderSynchronizer;
+OBJC_CLASS AVStreamSession;
 
 typedef struct OpaqueCMTimebase* CMTimebaseRef;
 
@@ -83,6 +84,8 @@
     void characteristicsChanged();
 
 #if ENABLE(ENCRYPTED_MEDIA_V2)
+    bool hasStreamSession() { return m_streamSession; }
+    AVStreamSession *streamSession();
     virtual void setCDMSession(CDMSession*) override;
     void keyNeeded(Uint8Array*);
 #endif
@@ -191,6 +194,7 @@
     RetainPtr<AVSampleBufferRenderSynchronizer> m_synchronizer;
     RetainPtr<id> m_timeJumpedObserver;
     RetainPtr<id> m_durationObserver;
+    RetainPtr<AVStreamSession> m_streamSession;
     Timer<MediaPlayerPrivateMediaSourceAVFObjC> m_seekTimer;
     CDMSessionMediaSourceAVFObjC* m_session;
     MediaPlayer::NetworkState m_networkState;

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


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm	2014-10-21 21:37:05 UTC (rev 174999)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm	2014-10-21 23:06:59 UTC (rev 175000)
@@ -57,6 +57,7 @@
 SOFT_LINK_CLASS_OPTIONAL(AVFoundation, AVSampleBufferDisplayLayer)
 SOFT_LINK_CLASS_OPTIONAL(AVFoundation, AVSampleBufferRenderSynchronizer)
 SOFT_LINK_CLASS_OPTIONAL(AVFoundation, AVStreamDataParser)
+SOFT_LINK_CLASS_OPTIONAL(AVFoundation, AVStreamSession);
 SOFT_LINK_CLASS_OPTIONAL(AVFoundation, AVVideoPerformanceMetrics)
 
 typedef struct opaqueCMNotificationCenter *CMNotificationCenterRef;
@@ -666,6 +667,13 @@
 }
 
 #if ENABLE(ENCRYPTED_MEDIA_V2)
+AVStreamSession* MediaPlayerPrivateMediaSourceAVFObjC::streamSession()
+{
+    if (!m_streamSession)
+        m_streamSession = adoptNS([[getAVStreamSessionClass() alloc] init]);
+    return m_streamSession.get();
+}
+
 void MediaPlayerPrivateMediaSourceAVFObjC::setCDMSession(CDMSession* session)
 {
     if (m_session) {
@@ -677,6 +685,7 @@
     m_session = toCDMSessionMediaSourceAVFObjC(session);
 
     if (m_session) {
+        m_session->setStreamSession(m_streamSession.get());
         for (auto& sourceBuffer : m_mediaSourcePrivate->sourceBuffers())
             m_session->addSourceBuffer(sourceBuffer.get());
     }

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


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.h	2014-10-21 21:37:05 UTC (rev 174999)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.h	2014-10-21 23:06:59 UTC (rev 175000)
@@ -80,6 +80,7 @@
     void didFailToParseStreamDataWithError(NSError*);
     void didProvideMediaDataForTrackID(int trackID, CMSampleBufferRef, const String& mediaType, unsigned flags);
     void didReachEndOfTrackWithTrackID(int trackID, const String& mediaType);
+    void willProvideContentKeyRequestInitializationDataForTrackID(int trackID);
     void didProvideContentKeyRequestInitializationDataForTrackID(NSData*, int trackID);
 
     bool processCodedFrame(int trackID, CMSampleBufferRef, const String& mediaType);

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


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm	2014-10-21 21:37:05 UTC (rev 174999)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm	2014-10-21 23:06:59 UTC (rev 175000)
@@ -28,6 +28,7 @@
 
 #if ENABLE(MEDIA_SOURCE) && USE(AVFOUNDATION)
 
+#import "BlockExceptions.h"
 #import "ExceptionCodePlaceholder.h"
 #import "Logging.h"
 #import "MediaDescription.h"
@@ -62,6 +63,7 @@
 SOFT_LINK_CLASS(AVFoundation, AVStreamDataParser)
 SOFT_LINK_CLASS(AVFoundation, AVSampleBufferAudioRenderer)
 SOFT_LINK_CLASS(AVFoundation, AVSampleBufferDisplayLayer)
+SOFT_LINK_CLASS(AVFoundation, AVStreamSession)
 
 SOFT_LINK_POINTER_OPTIONAL(AVFoundation, AVMediaTypeVideo, NSString *)
 SOFT_LINK_POINTER_OPTIONAL(AVFoundation, AVMediaTypeAudio, NSString *)
@@ -115,6 +117,14 @@
 #define AVMediaCharacteristicLegible getAVMediaCharacteristicLegible()
 
 #pragma mark -
+#pragma mark AVStreamSession
+
+@interface AVStreamSession : NSObject
+- (void)addStreamDataParser:(AVStreamDataParser *)streamDataParser;
+- (void)removeStreamDataParser:(AVStreamDataParser *)streamDataParser;
+@end
+
+#pragma mark -
 #pragma mark AVStreamDataParser
 
 @interface AVStreamDataParser : NSObject
@@ -268,6 +278,27 @@
     });
 }
 
+- (void)streamParserWillProvideContentKeyRequestInitializationData:(AVStreamDataParser *)streamDataParser forTrackID:(CMPersistentTrackID)trackID
+{
+#if ASSERT_DISABLED
+    UNUSED_PARAM(streamDataParser);
+#endif
+    ASSERT(streamDataParser == _parser);
+
+    if (isMainThread()) {
+        _parent->willProvideContentKeyRequestInitializationDataForTrackID(trackID);
+        return;
+    }
+
+    // We must call synchronously to the main thread, as the AVStreamSession must be associated
+    // with the streamDataParser before the delegate method returns.
+    RetainPtr<WebAVStreamDataParserListener> strongSelf = self;
+    dispatch_sync(dispatch_get_main_queue(), [strongSelf, trackID]() {
+        if (strongSelf->_parent)
+            strongSelf->_parent->willProvideContentKeyRequestInitializationDataForTrackID(trackID);
+    });
+}
+
 - (void)streamDataParser:(AVStreamDataParser *)streamDataParser didProvideContentKeyRequestInitializationData:(NSData *)initData forTrackID:(CMPersistentTrackID)trackID
 {
 #if ASSERT_DISABLED
@@ -658,6 +689,25 @@
     notImplemented();
 }
 
+void SourceBufferPrivateAVFObjC::willProvideContentKeyRequestInitializationDataForTrackID(int trackID)
+{
+    if (!m_mediaSource)
+        return;
+
+    ASSERT(m_parser);
+
+#if ENABLE(ENCRYPTED_MEDIA_V2)
+    LOG(MediaSource, "SourceBufferPrivateAVFObjC::willProvideContentKeyRequestInitializationDataForTrackID(%p) - track:%d", this, trackID);
+    m_protectedTrackID = trackID;
+
+    BEGIN_BLOCK_OBJC_EXCEPTIONS;
+    [m_mediaSource->player()->streamSession() addStreamDataParser:m_parser.get()];
+    END_BLOCK_OBJC_EXCEPTIONS;
+#else
+    UNUSED_PARAM(trackID);
+#endif
+}
+
 void SourceBufferPrivateAVFObjC::didProvideContentKeyRequestInitializationDataForTrackID(NSData* initData, int trackID)
 {
     if (!m_mediaSource)
@@ -733,6 +783,9 @@
 
 void SourceBufferPrivateAVFObjC::destroyParser()
 {
+    if (m_mediaSource->player()->hasStreamSession())
+        [m_mediaSource->player()->streamSession() removeStreamDataParser:m_parser.get()];
+
     [m_delegate invalidate];
     m_delegate = nullptr;
     m_parser = nullptr;

Modified: trunk/Source/WebCore/platform/mac/SoftLinking.h (174999 => 175000)


--- trunk/Source/WebCore/platform/mac/SoftLinking.h	2014-10-21 21:37:05 UTC (rev 174999)
+++ trunk/Source/WebCore/platform/mac/SoftLinking.h	2014-10-21 23:06:59 UTC (rev 175000)
@@ -236,7 +236,6 @@
         return constant##name; \
     }
 
-#if PLATFORM(IOS)
 #define SOFT_LINK_CONSTANT_MAY_FAIL(framework, name, type) \
     static bool init##name(); \
     static type (*get##name)() = 0; \
@@ -263,4 +262,3 @@
         get##name = name##Function; \
         return true; \
     }
-#endif
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to