Compartir a través de


Writing a Media Foundation Source that Interacts with the PlayReady Input Trust Authority (ITA)

Media sources are objects that generate media data. For example, the data might come from a video file, a network stream, or a hardware device, such as a camera. Each media source contains one or more streams, and each stream delivers data of one type, such as audio or video. For more information about media sources, see Media Sources.

An Input Trust Authority (ITA) is a component that implements an input protection system for media content. An ITA translates policy from the content's native format into a common format that is used by other protected media path (PMP) components. It also provides a decryptor, if one is needed to decrypt the stream.

This section describes how to add PlayReady ITA to a custom media source to provide support for protected content. For information on how to write a custom media source, see Writing a Custom Media Source.

Initializing the ITA

Usually, a player app will use the built-in PlayReady media source, but sometimes you might want to use a custom PlayReady media source. In this case, the media source needs to implement IMFTrustedInput so that the Media Foundation pipeline can get the ITA. In PlayReady Client SDK for Windows Store Apps, the Microsoft.Media.PlayReadyClient.PlayReadyWinRTTrustedInput class helps the source create the ITA. To instantiate this ITA, the media source needs to pass in some initialization data. The following schema describes how the initialization data should look.

  1. GUID—the content protection system GUID (see the referenced GUID—either CLSID_PlayReadySystemID, CLSID_WMDRMSystemID, or CLSID_WTVSystemID).
  2. DWORD—the stream count; use the actual stream count even if all streams are encrypted using the same data (note that zero is invalid).
  3. DWORD—the next stream identifier; use -1 if all remaining streams are encrypted using the same data or you are providing serialized IPropertySet values.
  4. DWORD—the next stream’s binary data size.
  5. BYTE* - the next stream’s binary data.
  6. Repeat steps 3, 4, and 5 for each stream.

For more information, see PlayReadyITADataFormat.

Passing in Samples

This section describes how the PlayReady ITA determines the encryption parameters of incoming samples and distinguishes between clear and encrypted samples. The following schema describes how state transitions work in the PlayReady ITA.

Look for a key identifier (KID) attribute on the sample.

If a KID exists then:

If the KID is GUID_NULL AND you don’t yet have a decryptor (and thus don’t yet have a KID):

  1. Then push the sample on (it’s a clear sample). This scenario should occur only when the content starts out clear. It should never occur once you see an encrypted sample.

Else if the KID is either identical to the current KID OR the KID is GUID_NULL, then perform decryption with the current decryptor.

Else (KID is different), then rotate to new decryptor and decrypt

If a KID doesn’t exist then:

If any other DRM-related attributes are set (for example, Sample ID) AND you don’t already have a decryptor (and thus don’t yet have a KID):

  1. Then push the sample on (it’s a clear sample). This scenario should only occur when the content starts out clear. It should never occur once you see an encrypted sample.

Else if any other DRM-related attributes are set (for example, Sample ID) AND you already have a decryptor, then decrypt with the current decryptor.

Else (no DRM attributes), then push the sample on (it’s a clear sample).

Note

If a key rotation event is ever sent with GUID_NULL for the KID, processing of the event will fail. Sources should make sure the KID is valid when sending a key rotation event.

Recommendations:

The source should not set any DRM attributes if the sample is clear. The following are the current DRM attributes supported by the ITA (this list is exhaustive).

PacketCrossOffsets – MFSampleExtension_PacketCrossOffsets, used for cocktail (the symmetric key algorithm used to encrypt content in the legacy Windows Media DRM ecosystem).

Sample ID – MFASFSampleExtension_Encryption_SampleID, used as part of the AES CTR IV.

KID – MFSampleExtension_Content_KeyID, note that even GUID_NULL for this attribute means “sample is encrypted”—see behavior above.

Sub-sample mapping / Sub-sample mapping split / Sample offsets—MFSampleExtension_Encryption_SubSampleMapping, MFSampleExtension_Encryption_SubSampleMappingSplit, MFSampleExtension_Encryption_SampleOffsets, all used to specify which part(s) of the sample to decrypt.

  • MFSampleExtension_Encryption_SubSampleMapping—The data blob associated with this attribute should contain an array of byte ranges as DWORDs where every two DWORDs make a set. The first DWORD in each set is the number of clear bytes and the second DWORD of the set is the number of encrypted bytes. Note that a pair of 0s is not a valid set (either value can be 0, but not both). The array of byte ranges indicate which ranges to decrypt, including the possibility that the entire sample should not be decrypted. This attribute must be set on an IMFSample using IMFAttribute.SetBlob.
  • MFSampleExtension_Encryption_SubSampleMappingSplit—This attribute is defined in mfapi.h as part of Media Foundation.
  • MFSampleExtension_Encryption_SampleOffsets—The data blob associated with this attribute should contain an array of two offsets as QWORDs. The first QWORD indicates which block within the AES sample being decrypted. The second QWORD indicates which byte within the AES block is being decrypted. Its value is expected to be within 0 and MAXBYTE. This attribute must be set on an IMFSample using IMFAttribute.SetBlob.

Setting the KID to a value other than GUID_NULL and a value that’s different than the current KID indicates key rotation.

To indicate “use the previous decryptor”, the source can set one or more of the aforementioned attributes (any subset) except as mentioned in the previous step (key rotation). To keep things simple Microsoft recommends you do the following:

  • If sample is clear, don’t set any DRM attributes.
  • If sample is encrypted, set the correct KID on every sample.
  • The source should never send a key rotation event with GUID_NULL for the KID.

How to Send a Key Rotation (KR) Event

This section describes how key rotation should be set up in the PlayReady media source.

Key Rotation in Windows 8.1

The source should send out an event with MfEvent type MEContentProtectionMetadata. The media stream uses this event to send protection system specific metadata to the decoder. For example, this event can be used to communicate a key rotation event. In this case, it should be sent as early as possible to give the decoder time to prepare itself before a sample encrypted with the new key identifier starts arriving.

The attributes for this event include the following:

  • MF_EVENT_STREAM_METADATA_KEYDATA – (Value: BLOB) Protection system specific data. This is an optional attribute.
  • MF_EVENT_STREAM_METADATA_CONTENT_KEYIDS – (Value: BLOB) Content key identifiers with which the event is associated.
  • MF_EVENT_STREAM_METADATA_SYSTEMID – (Value: BLOB) System identifier for which the key data is intended. This is an optional attribute.

See Also

Reference

PlayReadyITADataFormat Enumeration
PlayReadyITADataGenerator Class