Re: [EME] Support for multiple initData values in a single session?

tl;dr: Trying to reuse session objects for similar initData values raises a
lot of issues that we don't currently have good solutions for. I'm leaning
towards letting the application handle this, at least for now.

Details inline.

On Tue, Jun 26, 2012 at 10:14 AM, Mark Watson <watsonm@netflix.com> wrote:

>
>  On Jun 26, 2012, at 8:38 AM, Yang Sun wrote:
>
>
>
> On Sun, Jun 24, 2012 at 9:58 AM, David Dorwin <ddorwin@google.com> wrote:
>
>>
>>  On Tue, Jun 19, 2012 at 8:27 AM, Mark Watson <watsonm@netflix.com>wrote:
>>
>>> Hi David,
>>>
>>>  If we define a session by the rule that different sessions represent
>>> CDM state that needs a different lifecycle (create/update/delete), then
>>> there could at least be a one-to-many relationship between initData and
>>> sessions. i.e. the same initData block could be used to create multiple
>>> sessions.
>>>
>>  Yes, though that seems like a less likely use case. My concern is that
>> the current draft does not allow a many-to-one relationship (i.e. multiple
>> initData blocks within a single session) and whether that is a problem.
>>
>
>  It seems Mark mentionedthe one initData to many sessions?
> And you mentiened the many initData to one sessions.
> My question is one initData can generate multiple key request, it contain
> multiple metadata for multiple files?
> From the specification, it seems initData is per content file basis, and
> can only generate one key for one session.
>
>
>  The specification doesn't really lock this down either way right now.
>
>  One can easily imagine an initData in a file which contains all the
> initialization information for the key or keys needed for a bunch of
> associated files (for example all the files in a adaptive bitrate group).
>
>  Without any further specification, it could be up to the CDM to decide
> whether all these keys are managed within one session or whether multiple
> sessions are required.
>
>  What I believe we decided today was that, for simplicity, we could
> constrain it so that the CDM does not get to make this decision: one
> initData creates a single session. If the application gives the same
> initData again it gets the same session back (* - see below), not a new one
> (or more strictly, if the application provides two initData blocks to the
> same keysystem, then the CDM may determine that its part of the initData
> for these two is equivalent - in a key-system-specific sense - and return
> the same session for both).
>
>  What this means is that as a service provider, if I want to manage the
> lifecycle of the audio and video keys separately, say, I need separate
> initData for them. This seems pretty logical.
>
>  Equally, without further specification, it could be that within a single
> session the CDM decides to manage multiple keys. That's fine.
>
Do you really mean to say "the CDM decides"? I don't think the CDM should
decide which keys to manage. It should manage whatever keys are identified
in the initData. To address this, I propose something like the following:

The CDM should treat all key identifiers in the initData the same. That is,
it should generate a license request for all of them. <non-normative>For
example, regardless of whether one or more of the key IDs is already known
in a different session. In addition to being simpler, this avoids potential
problems if the other session is closed.</non-normative>


>  So, said another way, if a new initData is passed to the CDM, the CDM
> decides whether this is actually new, or simply repeats information it had
> before. If it's new, it creates a new session (specifically, it *does not*
> "update" an existing session). If just a repetition, then an existing
> session could be returned.
>
After thinking about this, I wonder if we really should return an existing
object. I believe the intent was that applications would not have to track
whether they had provided this initData already. This might be useful when
the audio and video streams are in separate files and have the same
initData and keys. However, I think it adds complexity to the API. My
specific concerns are:

   1. Locating the correct session may take time, something that would be
   better done asynchronously.
   2. The application will not know whether the returned object is an
   existing session. Thus, it will not know whether to expect a keymessage
   containing the license request. We could fire a keymessage anyway, but
   then we have not really accomplished anything because the application will
   still make a round trip to the server.


>  * from a Javascript point of view, I guess this might still be a
> different object, since when we return the object the CDM has not yet had a
> chance to process the initData. The three possibilities are (a) the new
> object gets the same session id as an existing one and essentially just
> duplicates the behavior of the existing one (b) you get an error event on
> this new object directing you to the already-existing session or (c) the
> CDM does get to process the initData synchronously.
>
The possible solutions to this issue illustrate some of my concerns above.
(a) does not seem to solve #2. (b) requires modifying the error event to
have a session object attribute; errors are fired at the session object, so
it's unclear what is returned. (c) may not be possible as mentioned in #1.

>
>
>
>
>
>
>>    I don't equate this as being a "single license exchange" - as per the
>>> other discussion on heartbeat and key rotation, the CDM can ask for a
>>> message exchange at any time and whether these message exchanges result in
>>> new 'licenses' inside the session state depends on how you define
>>> 'license'. Since we're not defining 'license' ourselves it must be up to
>>> the CDM.
>>>
>>  I was using "single license" to refer to the keys/permissions for a
>> single initData (i.e. key or set of keys for a single stream). I did not
>> mean to imply a limitation on what can occur within a session or how the
>> license might be obtained or maintained.
>>
>>  The current draft assumes generateKeyRequest is only called once (and
>> each time it is called, a new session ID is generated), so the
>> _application_ can only request key(s)/license(s) once per session. The CDM
>> can request new or renewed licenses (as in the heartbeat discussion), but
>> the application cannot (i.e. if it encounters new initData).
>>
>>>
>>>
>
>
>>    There are two approaches for the use case where a single session can
>>> be used to decrypt multiple files (e.g. audio/video).
>>> 1) we require that all the necessary initData is included in both files,
>>> so the session can be initialized with one initData and when the other file
>>> is encountered the CDM will discover that there is a session already
>>> created with all the necessary state (for example the initData contains the
>>> key ids and the CDM recognizes it already has those keys).
>>>
>>  I'd prefer not to do this since it imposes an artificial requirement on
>> the media files.
>>
>>
>>>  2) we would need to provide multiple initData blocks to a single
>>> session
>>>
>>  If we are going to support the use case, we probably need to do this.
>> We would need to decide how and whether all initData values (i.e. from
>> multiple files) need to be provided at the beginning or can be added later
>> (i.e. found later in the file or after a stream switch).
>>
>>>
>>>  In (2), it's not certain that providing additional initData to a
>>> session will result in a new message exchange.
>>>
>>  Is there a use case for providing additional initData other than to
>> cause a key/license for it to be requested? Or were you just observing this
>> might be the case, such as with the current APIs?
>>
>>>
>>>  Also, when new initData is encountered, who should decide whether a
>>> new session is required or whether this initData can be absorbed into an
>>> existing session ? Probably the CDM, right ?
>>>
>>  As with most things in the proposal, I think the application should be
>> responsible for making this decision. The initData is not known to the CDM
>> until the application provides it. (The media element provides it to the
>> app, not the CDM.)
>>
>
>  Suppose for example the initData in the audio file states that you need
> the keys with ids X and Y (which happen to be the keys for the audio *and
> video* for the session). The initData in the video files says that you
> need the keys with ids Y and X. The key ids are just listed in the opposite
> order, so the bytes of the initData in the audio and video files are
> different. Only the CDM can tell that they are asking for the same keys. So
> only the CDM would know that a new session is not needed when the second of
> these initData is passed in.
>
>  That is, unless we require the application to have a priori knowledge of
> whether the content needs separate sessions for the audio and video or not.
> A custom Netflix player would know this and would never pass in the second
> initData. But a generic player wouldn't know.
>

Hmm, I was assuming the the CDM would only do an exact match on the
initData and not the individual key identifiers within it. Then we would
have to start worrying about non-key ID data within the initData and
whether that is relevant.

Would the CDM also handle the case where separate initData's were provided
for key IDs X and Y and now a new initData with both X and Y is specified.
Also, the opposite case where X and Y were provided in one initData and a
new initData contains X or Y.

We would also need to specify whether simply having a session is sufficient
or whether the key must already exist. In the former case, it's possible
that the previous session failed, so we would somehow need to ensure that
session is closed/destroyed so we can request a new one.

>
>
>>
>>>  If we use the object-oriented design, do we just overload the method
>>> which creates a new session (from some initData) so that it can either
>>> create a new one or return an existing one ?
>>>
>>  I think that if we allow initData to be added, it would be via a new
>> method on the session object. This may look something like:
>> var session = video.createKeySession();
>> session.generateKeyRequest(initData1);
>> ...
>> session.addKey(keyForInitData1);
>> ...
>>  session.generateKeyRequest(initData2);
>> ...
>> session.addKey(keyForInitData2);
>>
>>  This results in multiple "license exchanges" within a single session.
>> The application could, of course, bundle them before sending them to the
>> server.
>>
>>  Since the exchanges share a single session ID and can be correlated in
>> that way, we probably don't need the ability to bundle multiple initData
>> values within the CDM (i.e. via generateKeyRequest()). I think supporting
>> that would complicate the API.
>>
>
>  Because we have multiple files, how we let session know which initData
> or key is for a certain file?
>
>
>  That's up to the CDM. For example, for any keysystem supporting ISO
> Common Encryption, the initData contains key ids and the samples themselves
> are also each linked to the key id needed to decrypt them.
>
>
>
>>
>>>  …Mark
>>>
>>>
>>>
>>>
>>>  On Jun 11, 2012, at 10:34 PM, David Dorwin wrote:
>>>
>>> In the current draft, each successful call to generateKeyRequest()
>>> generates a new session. Since initData is passed to generateKeyRequest(),
>>> each initData would be in a separate session. I'd like to get feedback on
>>> whether separating each initData into a separate session or object would be
>>> a problem.
>>>
>>>  Possible issues with only allowing one initData value per session
>>> include:
>>>  * Each session is a separate license exchange.
>>>  * Applications that care about session IDs will need to deal with
>>> multiple IDs.
>>>  * In the potential sessions as objects design (
>>> https://www.w3.org/Bugs/Public/show_bug.cgi?id=16613), each session
>>> would be a separate object.
>>>
>>>  The following are some possible scenarios where multiple initData
>>> values may occur:
>>>  * Audio and video are in separate files and have different initData.
>>>  * Different tracks or bitrates have different initData.
>>>  * A container supports multiple initData values.
>>>
>>>  To allow multiple initData values per session, we would either need to
>>> separate session creation from providing initData or allow an array of
>>> initData to be provided. Both solutions would work in both the current
>>> and sessions as objects designs. However, note that since needkey events
>>> may occur at different times, the application might not know when it has
>>> all initData values that it needs to send. In addition, initData values
>>> that are encountered later (i.e. after a stream switch or later in the
>>> container) could not be added to the session. Addressing that would
>>> probably require changing the 1:1 license/session ratio.
>>>
>>>
>>>
>>
>
>
>  --
> Yang
> Huawei
>
>
>

Received on Tuesday, 26 June 2012 19:54:33 UTC