Changeset 220962 in webkit


Ignore:
Timestamp:
Aug 21, 2017 5:56:44 AM (7 years ago)
Author:
zandobersek@gmail.com
Message:

[EME] HTMLMediaElement: basic implementations of 'Attempt to Decrypt', 'Attempt to Resume Playback If Necessary'
https://bugs.webkit.org/show_bug.cgi?id=175761

Reviewed by Xabier Rodriguez-Calvar.

Add initial and incomplete implementations of the 'Attempt to Decrypt' and
'Attempt to Resume Playback If Necessary' algorithms. The implementations
are interleaved with the specification text for clarity.

'Attempt to Decrypt' implementation doesn't yet address the encrypted block
queue or the 'decryption blocked waiting for key' flag since it's not yet
clear whether it would make more sense for this state to reside lower, in
the platform layer. The gist of the algorithm is to invoke the decryption
attempt through the MediaPlayer object, passing along the CDMInstance object
retrieved from the MediaKeys object that is associated with this media
element.

'Attempt to Resume Playback if Necessary' implementation similarly for now
omits the various state flag operations. The main task at this point is to
dispatch the 'Attempt to Decrypt' algorithm.

HTMLMediaElement::cdmClientAttemptToResumePlaybackIfNecessary() method now
invokes the attemptToResumePlaybackIfNecessary() method.

MediaKeys::hasOpenSessions() is introduced, returning true if any session
that was created through this MediaKeys instance is still open. This allows
the 'Attempt to Decrypt' algorithm to proceed with the decryption attempt
dispatch into the MediaPlayer hierarchy.

For that, the MediaPlayer::attemptToDecryptWithInstance() method is added,
which simply dispatches the mirror method on MediaPlayerPrivate interface.
This will enable the platform-layer implementations to use the passed-in
CDMInstance object for decryption purposes.

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

(WebCore::MediaKeys::hasOpenSessions const):

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

(WebCore::HTMLMediaElement::attemptToDecrypt):
(WebCore::HTMLMediaElement::attemptToResumePlaybackIfNecessary):
(WebCore::HTMLMediaElement::cdmClientAttemptToResumePlaybackIfNecessary):

  • html/HTMLMediaElement.h: Mark cdmClientAttemptToResumePlaybackIfNecessary() as final.
  • platform/graphics/MediaPlayer.cpp:

(WebCore::MediaPlayer::attemptToDecryptWithInstance):

  • platform/graphics/MediaPlayer.h:
  • platform/graphics/MediaPlayerPrivate.h:

(WebCore::MediaPlayerPrivateInterface::attemptToDecryptWithInstance):

Location:
trunk/Source/WebCore
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r220959 r220962  
     12017-08-21  Zan Dobersek  <zdobersek@igalia.com>
     2
     3        [EME] HTMLMediaElement: basic implementations of 'Attempt to Decrypt', 'Attempt to Resume Playback If Necessary'
     4        https://bugs.webkit.org/show_bug.cgi?id=175761
     5
     6        Reviewed by Xabier Rodriguez-Calvar.
     7
     8        Add initial and incomplete implementations of the 'Attempt to Decrypt' and
     9        'Attempt to Resume Playback If Necessary' algorithms.  The implementations
     10        are interleaved with the specification text for clarity.
     11
     12        'Attempt to Decrypt' implementation doesn't yet address the encrypted block
     13        queue or the 'decryption blocked waiting for key' flag since it's not yet
     14        clear whether it would make more sense for this state to reside lower, in
     15        the platform layer. The gist of the algorithm is to invoke the decryption
     16        attempt through the MediaPlayer object, passing along the CDMInstance object
     17        retrieved from the MediaKeys object that is associated with this media
     18        element.
     19
     20        'Attempt to Resume Playback if Necessary' implementation similarly for now
     21        omits the various state flag operations. The main task at this point is to
     22        dispatch the 'Attempt to Decrypt' algorithm.
     23
     24        HTMLMediaElement::cdmClientAttemptToResumePlaybackIfNecessary() method now
     25        invokes the attemptToResumePlaybackIfNecessary() method.
     26
     27        MediaKeys::hasOpenSessions() is introduced, returning true if any session
     28        that was created through this MediaKeys instance is still open. This allows
     29        the 'Attempt to Decrypt' algorithm to proceed with the decryption attempt
     30        dispatch into the MediaPlayer hierarchy.
     31
     32        For that, the MediaPlayer::attemptToDecryptWithInstance() method is added,
     33        which simply dispatches the mirror method on MediaPlayerPrivate interface.
     34        This will enable the platform-layer implementations to use the passed-in
     35        CDMInstance object for decryption purposes.
     36
     37        * Modules/encryptedmedia/MediaKeySession.h:
     38        * Modules/encryptedmedia/MediaKeys.cpp:
     39        (WebCore::MediaKeys::hasOpenSessions const):
     40        * Modules/encryptedmedia/MediaKeys.h:
     41        * html/HTMLMediaElement.cpp:
     42        (WebCore::HTMLMediaElement::attemptToDecrypt):
     43        (WebCore::HTMLMediaElement::attemptToResumePlaybackIfNecessary):
     44        (WebCore::HTMLMediaElement::cdmClientAttemptToResumePlaybackIfNecessary):
     45        * html/HTMLMediaElement.h: Mark cdmClientAttemptToResumePlaybackIfNecessary() as final.
     46        * platform/graphics/MediaPlayer.cpp:
     47        (WebCore::MediaPlayer::attemptToDecryptWithInstance):
     48        * platform/graphics/MediaPlayer.h:
     49        * platform/graphics/MediaPlayerPrivate.h:
     50        (WebCore::MediaPlayerPrivateInterface::attemptToDecryptWithInstance):
     51
    1522017-08-20  Zan Dobersek  <zdobersek@igalia.com>
    253
  • trunk/Source/WebCore/Modules/encryptedmedia/MediaKeySession.h

    r220905 r220962  
    6161    using RefCounted<MediaKeySession>::deref;
    6262
     63    bool isClosed() const { return m_closed; }
    6364    void detachKeys();
    6465
  • trunk/Source/WebCore/Modules/encryptedmedia/MediaKeys.cpp

    r220905 r220962  
    135135}
    136136
     137bool MediaKeys::hasOpenSessions() const
     138{
     139    return std::any_of(m_sessions.begin(), m_sessions.end(),
     140        [](auto& session) {
     141            return !session->isClosed();
     142        });
     143}
     144
    137145} // namespace WebCore
    138146
  • trunk/Source/WebCore/Modules/encryptedmedia/MediaKeys.h

    r220959 r220962  
    6464    void attemptToResumePlaybackOnClients();
    6565
     66    bool hasOpenSessions() const;
    6667    const CDMInstance& cdmInstance() const { return m_instance; }
    6768
  • trunk/Source/WebCore/html/HTMLMediaElement.cpp

    r220959 r220962  
    26492649}
    26502650
     2651void HTMLMediaElement::attemptToDecrypt()
     2652{
     2653    // https://w3c.github.io/encrypted-media/#attempt-to-decrypt
     2654    // W3C Editor's Draft 23 June 2017
     2655
     2656    // 1. Let the media element be the specified HTMLMediaElement object.
     2657    // 2. If the media element's encrypted block queue is empty, abort these steps.
     2658    // FIXME: ^
     2659
     2660    // 3. If the media element's mediaKeys attribute is not null, run the following steps:
     2661    if (m_mediaKeys) {
     2662        // 3.1. Let media keys be the MediaKeys object referenced by that attribute.
     2663        // 3.2. Let cdm be the CDM instance represented by media keys's cdm instance value.
     2664        auto& cdmInstance = m_mediaKeys->cdmInstance();
     2665
     2666        // 3.3. If cdm is no longer usable for any reason, run the following steps:
     2667        //   3.3.1. Run the media data is corrupted steps of the resource fetch algorithm.
     2668        //   3.3.2. Run the CDM Unavailable algorithm on media keys.
     2669        //   3.3.3. Abort these steps.
     2670        // FIXME: ^
     2671
     2672        // 3.4. If there is at least one MediaKeySession created by the media keys that is not closed, run the following steps:
     2673        if (m_mediaKeys->hasOpenSessions()) {
     2674            // Continued in MediaPlayer::attemptToDecryptWithInstance().
     2675            if (m_player)
     2676                m_player->attemptToDecryptWithInstance(cdmInstance);
     2677        }
     2678    }
     2679
     2680    // 4. Set the media element's decryption blocked waiting for key value to true.
     2681    // FIXME: ^
     2682}
     2683
    26512684void HTMLMediaElement::attemptToResumePlaybackIfNecessary()
    26522685{
     
    26542687    // W3C Editor's Draft 23 June 2017
    26552688
    2656     notImplemented();
     2689    // 1. Let the media element be the specified HTMLMediaElement object.
     2690    // 2. If the media element's playback blocked waiting for key is false, abort these steps.
     2691    // FIXME: ^
     2692
     2693    // 3. Run the Attempt to Decrypt algorithm on the media element.
     2694    attemptToDecrypt();
     2695
     2696    // 4. If the user agent can advance the current playback position in the direction of playback:
     2697    //   4.1. Set the media element's decryption blocked waiting for key value to false.
     2698    //   4.2. Set the media element's playback blocked waiting for key value to false.
     2699    //   4.3. Set the media element's readyState value to HAVE_CURRENT_DATA, HAVE_FUTURE_DATA or HAVE_ENOUGH_DATA as appropriate.
     2700    // FIXME: ^
    26572701}
    26582702
    26592703void HTMLMediaElement::cdmClientAttemptToResumePlaybackIfNecessary()
    26602704{
    2661     notImplemented();
     2705    attemptToResumePlaybackIfNecessary();
    26622706}
    26632707
  • trunk/Source/WebCore/html/HTMLMediaElement.h

    r220959 r220962  
    637637
    638638#if ENABLE(ENCRYPTED_MEDIA)
     639    void attemptToDecrypt();
    639640    void attemptToResumePlaybackIfNecessary();
    640641
    641642    // CDMClient
    642     void cdmClientAttemptToResumePlaybackIfNecessary() override;
     643    void cdmClientAttemptToResumePlaybackIfNecessary() final;
    643644#endif
    644645   
  • trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp

    r220959 r220962  
    595595    m_private->cdmInstanceDetached(instance);
    596596}
     597
     598void MediaPlayer::attemptToDecryptWithInstance(const CDMInstance& instance)
     599{
     600    m_private->attemptToDecryptWithInstance(instance);
     601}
    597602#endif
    598603
  • trunk/Source/WebCore/platform/graphics/MediaPlayer.h

    r220959 r220962  
    372372    void cdmInstanceAttached(const CDMInstance&);
    373373    void cdmInstanceDetached(const CDMInstance&);
     374    void attemptToDecryptWithInstance(const CDMInstance&);
    374375#endif
    375376
  • trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h

    r220959 r220962  
    240240    virtual void cdmInstanceAttached(const CDMInstance&) { }
    241241    virtual void cdmInstanceDetached(const CDMInstance&) { }
     242    virtual void attemptToDecryptWithInstance(const CDMInstance&) { }
    242243#endif
    243244
Note: See TracChangeset for help on using the changeset viewer.