Wasabi ExpressPlay SDK for Desktop Systems  1.23.0
Data Structures | Typedefs | Enumerations | Functions
WSB_MediaStream Class

A general Marlin protected data access interface. More...

Data Structures

struct  WSB_MediaStreamInterface
 
struct  WSB_MediaStream
 
union  WSB_MediaStream_FormatInfo
 Source data format information. More...
 

Typedefs

typedef struct WSB_MediaStream WSB_MediaStream
 
typedef struct WSB_KeyManager WSB_MediaStreamKey
 

Enumerations

enum  WSB_MediaStream_SourceType {
  WSB_MEDIASTREAM_SOURCE_TYPE_DCF,
  WSB_MEDIASTREAM_SOURCE_TYPE_AES128CBC,
  WSB_MEDIASTREAM_SOURCE_TYPE_AES128CTR
}
 

Functions

WSB_EXPORT WSB_Result WSB_MediaStream_OpenUrl (const char *source_url, WSB_MediaStream_SourceType source_type, const WSB_MediaStream_FormatInfo *format_info, WSB_MediaStream **stream)
 Open a Marlin protected source. More...
 
WSB_EXPORT WSB_Result WSB_MediaStream_Open (WSB_MediaStream *source_stream, const WSB_MediaStream_FormatInfo *format_info, WSB_MediaStream **stream)
 Open a Marlin protected source stream. More...
 
WSB_EXPORT WSB_Result WSB_MediaStream_Read (WSB_MediaStream *self, void *buffer, WSB_Size *read_bytes)
 Read data from a media stream object. More...
 
WSB_EXPORT WSB_Result WSB_MediaStream_Seek (WSB_MediaStream *self, WSB_Position position)
 Change the current read position for a media stream. More...
 
WSB_EXPORT WSB_Result WSB_MediaStream_Tell (WSB_MediaStream *self, WSB_Position *position)
 Get the current read position for a media stream. More...
 
WSB_EXPORT WSB_Result WSB_MediaStream_GetSize (WSB_MediaStream *self, WSB_LargeSize *size)
 Get the size of the media stream in bytes, if known (or an error code if the size is unknown or an error occurs). More...
 
WSB_EXPORT WSB_Result WSB_MediaStream_GetContentType (WSB_MediaStream *self, const char **content_type)
 Get the content type of the data in the media stream. More...
 
WSB_EXPORT WSB_Result WSB_MediaStream_GetKey (WSB_MediaStream *self, const WSB_MediaStreamKey **key)
 Extract the crypto context from a Media Stream object. More...
 
WSB_EXPORT WSB_Result WSB_MediaStream_Close (WSB_MediaStream *self)
 Release a media stream object once it is no longer needed. More...
 

Detailed Description

A general Marlin protected data access interface.

The Media Stream API provides access to Marlin DRM protected application data of arbitrary and generic type. There are three mostly independent aspects of setting up a Media Stream object to gain access to the underlying clear data:

Support for each of these three items in Media Stream API is described in the following. Afterwards, a few common pseudo-code examples are provided.

  1. Source Type (or Data Format):
    1. DCF - Open Mobile Alliance DRM Content Format:
      DCF includes headers that carry important information about the protected data: the original clear data size, the IV, the content ID, and content type of the clear data. Data must be packaged properly and contain all the mentioned pieces of information.
    2. Raw AES128CBC encrypted data (optional IV as the first block):
      The data is encrypted with AES-128 in CBC mode as one large chunk (see http://www.w3.org/TR/xmlenc-core/#sec-Alg-Block for the padding scheme used at the end.) If the IV is not included at the beginning of the data, then it must be included in the WSB_MediaStream_FormatInfo structure. The clear data size can be provided in the WSB_MediaStream_FormatInfo structure, or it can be computed from the data, but may be less efficient and may not be supported if the access is through HTTP.
    3. Raw AES128CTR encrypted data:
      The data is encrypted with AES-128 in CTR mode. IV and counter size must be provided in the WSB_MediaStream_FormatInfo structure. The clear text data is of the same length as the encrypted data.
  2. Data Access Method:
    1. http:// or file:// URL:
      Encrypted data is accessed through the standard HTTP protocol, or through direct file access. In case of direct file access, a file:// URL or a relative or absolute file path may be provided to the WSB_MediaStream_OpenUrl.
    2. MS3 URL, e.g. https://, ms3:// and similar:
      The content URL is the C-URL of the compound MS3 URL provided to the WSB_MediaStream_OpenUrl method. The content URL can be http:// or file:// URL as in previous case (but not a plain file path).
    3. An object implementing the WSB_MediaStreamInterface:
      In some use cases, the protected data is not available through the standard HTTP or file access methods. In such cases, application provides access to the protected data through an object that implements methods of the WSB_MediaStreamInterface structure.
  3. Key Retrieval Method:
    1. Marlin BB license:
      The Marlin BB license must be acquired by the application and then either provided explicitly in the WSB_MediaStream_FormatInfo structure or stored in the License Store to be found by the run-time as necessary.
    2. Marlin MS3 URL:
      The Media Stream can access content keys through an MS3 URL. The MS3 URL may be provided to WSB_MediaStream_OpenUrl, or it may be provided in the WSB_MediaStream_FormatInfo structure when using the WSB_MediaStream_Open, i.e. when using a WSB_MediaStreamInterface object that provides access to protected data.
    3. Reference a key object from another MediaStream instance:
      The Media Stream API provides an efficient way of instantiating multiple Media Stream objects with the same DRM keys, and the corresponding license being processed only once. The application may use either BB license or MS3 URL for the construction of an initial Media Stream object, and then instantiate subsequent Media Stream objects through the shared key object provided in the WSB_MediaStream_FormatInfo structure, obtained from the initial Media Stream object through the WSB_MediaStream_GetKey method.

USAGE EXAMPLES:

The following Media Stream API usage examples illustrate some of the common use cases:

  1. Local DCF file with BB license
    WSB_Result result;
    
    // Initialize the run-time
    result = WSB_Runtime_Initialize();
    CHECK_RESULT(result);
    
    // perform personalization if necessary...
    
    const char* token;
    
    // The token must be acquired from HMS or other similar Marlin
    // server.
    AcquireBbLicenseToken(&token);
    
    // Load the BB license.
    result = WSB_Runtime_ProcessServiceToken(token, strlen(token));
    CHECK_RESULT(result);
    
    WSB_MediaStream* media_stream;
    WSB_Size read_count;
    WSB_LargeSize size;
    
    result = WSB_MediaStream_OpenUrl("/data/my-file.dcf", 
                                     WSB_MEDIASTREAM_SOURCE_TYPE_DCF,
                                     NULL, // no format_info needed
                                     &media_stream);
    CHECK_RESULT(result);
    
    result = WSB_MediaStream_GetSize(media_stream, &size);
    CHECK_RESULT(result);
    
    while (size > 0) {
        WSB_UInt8 buffer[BUF_SIZE];
    
        read_count = MIN(sizeof(buffer), size); // number of bytes to read
    
        result = WSB_MediaStream_Read(media_stream, buffer, &read_count);
        CHECK_RESULT(result);
    
        ProcessData(buffer, read_count); // read_count is set to the
                                         // number of actually read
                                         // bytes
        size -= read_count;
    }
    
    result = WSB_MediaStream_Close(media_stream);
    CHECK_RESULT(result);
    
    result = WSB_Runtime_Terminate();
    CHECK_RESULT(result);
    
  2. HTTP AES128CBC URL with MS3 license, inline IV
    WSB_Result result;
    
    // Initialize the run-time
    result = WSB_Runtime_Initialize();
    CHECK_RESULT(result);
    
    // perform personalization if necessary...
    
    WSB_MediaStream_FormatInfo format_info;
    WSB_MediaStream* media_stream;
    WSB_Size read_count;
    WSB_LargeSize size;
    const char* ms3_url;
    
    // Application must acquire an MS3 URL.
    AcquireMs3Url(&ms3_url);
    
    memset(&format_info, 0, sizeof(format_info));
    
    // Application must know the content ID
    format_info.common.content_id = "test-content-id-or-some-such"; 
    // Application should set clear text size when accessing over HTTP
    format_info.common.clear_text_size = 12345;
    result = WSB_MediaStream_OpenUrl(ms3_url, 
                                     WSB_MEDIASTREAM_SOURCE_TYPE_AES128CBC,
                                     &format_info, 
                                     &media_stream);
    CHECK_RESULT(result);
    
    result = WSB_MediaStream_GetSize(media_stream, &size);
    CHECK_RESULT(result);
    
    while (size > 0) {
        WSB_UInt8 buffer[BUF_SIZE];
    
        read_count = MIN(sizeof(buffer), size); // number of bytes to read
    
        result = WSB_MediaStream_Read(media_stream, buffer, &read_count);
        CHECK_RESULT(result);
    
        ProcessData(buffer, read_count); // read_count is set to the
                                         // number of actually read
                                         // bytes
        size -= read_count;
    }
    
    result = WSB_MediaStream_Close(media_stream);
    CHECK_RESULT(result);
    
    result = WSB_Runtime_Terminate();
    CHECK_RESULT(result);
    
  3. CENC media sample decryption with MS3 license

    In this example, each media sample is decrypted using a separate Media Stream instance. The pseudo code shows the setup for the first decrypting Media Stream object, and then for all the others.

    WSB_Result result;
    
    // Initialize the run-time
    result = WSB_Runtime_Initialize();
    CHECK_RESULT(result);
    
    // perform personalization if necessary...
    
    WSB_MediaStream_FormatInfo format_info;
    WSB_MediaStream* first_media_stream;
    WSB_Size read_count;
    WSB_LargeSize size;
    const char* ms3_url;
    
    memset(&format_info, 0, sizeof(format_info));
    
    // The first decrypting Media Stream object acquires content keys
    // from the MS3 URL
    
    // Application must acquire an MS3 URL.
    AcquireMs3Url(&ms3_url);
    format_info.common.ms3_url = ms3_url;
    
    // Application must know the content ID
    format_info.common.content_id = "test-content-id-or-some-such"; 
    
    // Application must know the IV
    unsigned char iv[16] = {...};
    format_info.common.iv = iv;
    
    // CENC counter size is 8
    format_info.common.counter_size = 8;
    
    // Application must create an object that implements the
    // MediaStreamInterface that can read encrypted media sample data.
    // The WSB_MediaStreamInterface.GetContentType must return 
    // WSB_MEDIASTREAM_CONTENT_TYPE_AES128CTR in this case and the
    // WSB_MediaStreamInterface.GetKey should return NULL for
    // WSB_MediaStreamKey.
    WSB_MediaStream* media_sample_reader = new ApplicationMediaStream(...);
    
    // The content keys are computed internally based on the MS3 URL and
    // content id in the format_info structure in this case.  In other
    // case (not in this example) where BB license is used, the content
    // keys are computed internally based on the BB license data and
    // content id in the format_info structure or valid BB license found
    // in LicenseStore that matches the content id in the format_info
    // structure.
    result = WSB_MediaStream_Open(media_sample_reader, &format_info, &first_media_stream);
    CHECK_RESULT(result);
    
    result = WSB_MediaStream_GetSize(first_media_stream, &size);
    CHECK_RESULT(result);
    
    while (size > 0) {
        WSB_UInt8 buffer[BUF_SIZE];
    
        read_count = MIN(sizeof(buffer), size); // number of bytes to read
    
        result = WSB_MediaStream_Read(first_media_stream, buffer, &read_count);
        CHECK_RESULT(result);
    
        ProcessData(buffer, read_count); // read_count is set to the
                                         // number of actually read
                                         // bytes
        size -= read_count;
    }
    
    ApplicationDestroyMediaSampleReader(media_sample_reader);
    
    // Must not close the first decrypting Media Stream object until
    // all media samples have been processed, as the first Media Stream
    // object owns the content keys.
    
    
    // Subsequent decrypting Media Stream objects reuse the content
    // keys from the first Media Stream
    WSB_MediaStream* media_stream;
    
    memset(&format_info, 0, sizeof(format_info));
    
    // Reuse the content keys from the first Media Stream object, no
    // license processing involved, fast Media Stream instantiation
    result = WSB_MediaStream_GetKey(first_media_stream, &format_info.common.key);
    CHECK_RESULT(result);
    
    // Application must know the content ID
    format_info.common.content_id = "test-content-id-or-some-such"; 
    
    // Application must know the IV
    unsigned char iv[16] = {...};
    format_info.common.iv = iv;
    
    // CENC counter size is 8
    format_info.common.counter_size = 8;
    
    // Application must create an object that implements the
    // MediaStreamInterface that can read encrypted media sample data.
    // The WSB_MediaStreamInterface.GetContentType must return 
    // WSB_MEDIASTREAM_CONTENT_TYPE_AES128CTR in this case and the
    // WSB_MediaStreamInterface.GetKey should return NULL for
    // WSB_MediaStreamKey.
    media_sample_reader = new ApplicationMediaStream(...);
    
    // New Media Stream object using existing content keys specified in
    // the format_info structure.
    result = WSB_MediaStream_Open(media_sample_reader, &format_info, &media_stream);
    CHECK_RESULT(result);
    
    result = WSB_MediaStream_GetSize(media_stream, &size);
    CHECK_RESULT(result);
    
    while (size > 0) {
        WSB_UInt8 buffer[BUF_SIZE];
    
        read_count = MIN(sizeof(buffer), size); // number of bytes to read
    
        result = WSB_MediaStream_Read(media_stream, buffer, &read_count);
        CHECK_RESULT(result);
    
        ProcessData(buffer, read_count); // read_count is set to the
                                         // number of actually read
                                         // bytes
        size -= read_count;
    }
    
    ApplicationDestroyMediaSampleReader(media_sample_reader);
    
    result = WSB_MediaStream_Close(media_stream);
    CHECK_RESULT(result);
    
    // Repeat media sample decryption with new Media Stream objects
    // ...
    
    // At the end, close the first Media Stream object.
    result = WSB_MediaStream_Close(first_media_stream);
    CHECK_RESULT(result);
    
    result = WSB_Runtime_Terminate();
    CHECK_RESULT(result);
    
Since
1.6

Typedef Documentation

◆ WSB_MediaStream

◆ WSB_MediaStreamKey

typedef struct WSB_KeyManager WSB_MediaStreamKey

Enumeration Type Documentation

◆ WSB_MediaStream_SourceType

Enumerator
WSB_MEDIASTREAM_SOURCE_TYPE_DCF 

Marlin DCF document format.

WSB_MEDIASTREAM_SOURCE_TYPE_AES128CBC 

See http://www.w3.org/TR/xmlenc-core/#sec-Alg-Block for the encryption format.

The IV block of 16 bytes may be prepended to the encrypted block for easy reference, but could also be omitted from the data and provided through the API in the WSB_MediaStream_FormatInfo.common.iv.

WSB_MEDIASTREAM_SOURCE_TYPE_AES128CTR 

The basic AES128CTR cipher protected data.

Ultimately can be used to implement CENC (Common Encryption) decryption, as found in MPEG DASH.

Function Documentation

◆ WSB_MediaStream_Close()

WSB_EXPORT WSB_Result WSB_MediaStream_Close ( WSB_MediaStream self)

Release a media stream object once it is no longer needed.

Parameters
selfthe media stream object.

◆ WSB_MediaStream_GetContentType()

WSB_EXPORT WSB_Result WSB_MediaStream_GetContentType ( WSB_MediaStream self,
const char **  content_type 
)

Get the content type of the data in the media stream.

If the content type is not known an error code is returned.

Parameters
selfthe media stream object.
content_typepointer to where the 0-terminated content type string is returned. The returned string is owned by the media stream object and is valid for the lifetime of the media stream object.

◆ WSB_MediaStream_GetKey()

WSB_EXPORT WSB_Result WSB_MediaStream_GetKey ( WSB_MediaStream self,
const WSB_MediaStreamKey **  key 
)

Extract the crypto context from a Media Stream object.

A new Media Stream object can be constructed efficiently using such crypto context in place of MS3 or BB license.

Parameters
selfthe media stream object.
keypointer to an opaque crypto context object pointer. The returned object remains owned by the current Media Stream and remains valid for the duration of the owner Media Stream object.
Returns
WSB_SUCCESS on success or WSB_ERROR_NOT_SUPPORTED if this Media Stream object does not support this method.
Since
1.8

◆ WSB_MediaStream_GetSize()

WSB_EXPORT WSB_Result WSB_MediaStream_GetSize ( WSB_MediaStream self,
WSB_LargeSize size 
)

Get the size of the media stream in bytes, if known (or an error code if the size is unknown or an error occurs).

Parameters
selfthe media stream object.
sizepointer to where the media stream size is returned.

◆ WSB_MediaStream_Open()

WSB_EXPORT WSB_Result WSB_MediaStream_Open ( WSB_MediaStream source_stream,
const WSB_MediaStream_FormatInfo format_info,
WSB_MediaStream **  stream 
)

Open a Marlin protected source stream.

Returns a WSB_MediaStream object that allows random access to the source data in cleartext. The returned object must be destroyed through WSB_MediaStream_Close.

Parameters
source_streama random access input stream object implementing the WSB_MediaStream_Interface interface. Client must ensure this object exists for the duration of the returned stream object.
format_infofurther information about the source data, that otherwise may not be available in the source data directly. Can be NULL.
streampointer to where the pointer to the newly created object is returned.

◆ WSB_MediaStream_OpenUrl()

WSB_EXPORT WSB_Result WSB_MediaStream_OpenUrl ( const char *  source_url,
WSB_MediaStream_SourceType  source_type,
const WSB_MediaStream_FormatInfo format_info,
WSB_MediaStream **  stream 
)

Open a Marlin protected source.

Returns a WSB_MediaStream object that allows random access to the source data in cleartext. The returned object must be destroyed through WSB_MediaStream_Close.

Parameters
source_urleither an ms3:// URL or directly a source file URL (http:// or file://) for BB.
source_typethe format type of the source data. See WSB_MediaStream_SourceType.
format_infofurther information about the source data, that otherwise may not be available in the source data directly. Can be NULL.
streampointer to where the pointer to the newly created object is returned.

NOTE: the BB license or MS3 SAS used with MediaStream must relax the default marlin output controls or the content will not be decrypted. This requires the SAS to carry an MS3 extension (of type “wudo”) or a the Marlin Broadband license to indicate a Marlin Broadband output control override (type “urn:marlin:organization:intertrust:wudo”).

◆ WSB_MediaStream_Read()

WSB_EXPORT WSB_Result WSB_MediaStream_Read ( WSB_MediaStream self,
void *  buffer,
WSB_Size read_bytes 
)

Read data from a media stream object.

The requested number of bytes and the actually read number of bytes is passed in and returned through *read_bytes. The number of actually read bytes can be less than requested.

At the end of data, WSB_ERROR_EOS is returned.

Parameters
selfthe media stream object.
bufferpointer to the data buffer of at least *read_bytes bytes.
read_bytesthe number of bytes requested as input parameter, the number of bytes actually read as output parameter.

NOTE: the BB license or MS3 SAS used with MediaStream must relax the default marlin output controls or the content will not be decrypted. This requires the SAS to carry an MS3 extension (of type “wudo”) or a the Marlin Broadband license to indicate a Marlin Broadband output control override (type “urn:marlin:organization:intertrust:wudo”).

◆ WSB_MediaStream_Seek()

WSB_EXPORT WSB_Result WSB_MediaStream_Seek ( WSB_MediaStream self,
WSB_Position  position 
)

Change the current read position for a media stream.

Parameters
selfthe media stream object.
positionthe number of bytes from the start of the media stream.

◆ WSB_MediaStream_Tell()

WSB_EXPORT WSB_Result WSB_MediaStream_Tell ( WSB_MediaStream self,
WSB_Position position 
)

Get the current read position for a media stream.

Parameters
selfthe media stream object.
positionpointer to where the current media stream position as the number of bytes from the start of the media stream is returned.