@startuml autonumber box "Container" #LightGreen participant Cobalt participant Starboard participant GStreamer_client participant rialtoClient end box box "Platform" #LightBlue participant rialtoServer participant GStreamer_server end box == Create Media Pipeline == Cobalt -> Starboard: SbPlayerCreate(media_keys_handle, video_info, audio_info) Starboard -> GStreamer_client: Create Gst pipeline with Rialto sinks activate GStreamer_client opt maxWidth Starboard -> GStreamer_client: Set PROP_MAX_VIDEO_WIDTH end opt maxHeight Starboard -> GStreamer_client: Set PROP_MAX_VIDEO_HEIGHT end note right of GStreamer_client As the Gst pipeline is brought up the creation of the first rialto sink for a pipeline triggers the createMediaPipeline() call. Creation of additional rialto sinks increments a ref count to the media pipeline. To identify which pipeline a sink relates to it will pass the parent bin object pointer to the pipeline root element. end note note right of GStreamer_client If max width and max height are not set by the client the mediaPipeline shall be created with videoRequirements set to 2160x3840. If max width and max height are set, then rialto shall assume the playback is secondary video. end note GStreamer_client -> rialtoClient: createMediaPipeline(client, videoRequirements) rialtoClient -> rialtoServer: createMediaPipeline(client, videoRequirements) rialtoServer -> rialtoServer: Check resource permissions that were granted to app and currently\nallocated pipelines allows creation of this new pipeline note left: Currently this check is simply num_current_pipeline_sessions < max_playback_sessions opt Permission check passed rialtoServer -> rialtoServer: Store video requirements rialtoServer --> rialtoClient: pipeline_session rialtoClient --> GStreamer_client: pipeline_session GStreamer_client -> rialtoClient: load(pipeline_session, MEDIA_TYPE_MSE, ~"", ~""). rialtoClient -> rialtoServer: load(pipeline_session, MEDIA_TYPE_MSE, ~"", ~"") rialtoServer -> GStreamer_server: Create rialto server MSE pipeline GStreamer_server --> rialtoServer: opt videoRequirements != 2160x3840 && westerossink rialtoServer -> GStreamer_server: Set secondary video GStreamer_server --> rialtoServer: end rialtoServer -/ rialtoClient: notifyNetworkState(pipeline_session, NETWORK_STATE_BUFFERING) rialtoClient -/ GStreamer_client: notifyNetworkState(pipeline_session, NETWORK_STATE_BUFFERING) rialtoServer --> rialtoClient: rialtoClient --> GStreamer_client: opt video_codec != None GStreamer_client -> rialtoClient: attachSource(pipeline_session, video_source) rialtoClient -> rialtoServer: attachSource(pipeline_session, video_source) rialtoServer -> GStreamer_server: Add video sink to pipeline GStreamer_server --> rialtoServer: rialtoServer --> rialtoClient: rialtoClient --> GStreamer_client: end opt audio_codec != None GStreamer_client -> rialtoClient: attachSource(pipeline_session, audio_source) rialtoClient -> rialtoServer: attachSource(pipeline_session, audio_source) rialtoServer -> GStreamer_server: Add audio sink to pipeline GStreamer_server --> rialtoServer: rialtoServer --> rialtoClient: rialtoClient --> GStreamer_client: end rialtoClient -> rialtoServer: allSourcesAttached(pipeline_session) rialtoServer -> GStreamer_server: Setup and add app source GStreamer_server --> rialtoServer: rialtoServer --> rialtoClient: deactivate GStreamer_client GStreamer_client --> Starboard Starboard --> Cobalt: == Notify that Pipeline & network session is currently IDLE == rialtoServer -/ rialtoClient: notifyNetworkState(NETWORK_STATE_IDLE) note right Note that notification may occur before createMediaPipeline() call returns end note rialtoClient -/ GStreamer_client: notifyNetworkState(NETWORK_STATE_IDLE) rialtoServer -/ rialtoClient: notifyPlaybackState(PLAYBACK_STATE_IDLE) note right Note that notification may occur before createMediaPipeline() call returns end note rialtoClient -/ GStreamer_client: notifyPlaybackState(PLAYBACK_STATE_IDLE) else Permission check failed rialtoServer --> rialtoClient: ERROR_DENIED rialtoClient --> GStreamer_client: ERROR_DENIED end @enduml |
@startuml autonumber box "Container" #LightGreen participant Cobalt participant Starboard participant GStreamer_client participant rialtoClient end box box "Platform" #LightBlue participant rialtoServer participant GStreamer_server end box Cobalt -> Starboard: SbPlayerDestroy(player_session) Starboard -> GStreamer_client: Destroy Rialto Client Gst pipeline activate GStreamer_client note right of GStreamer_client As each rialto sink is freed it will decrement the ref count to its media player (via the TBD unique pipeline ID). When the ref count reaches zero the destructor is triggered. end note GStreamer_client -> rialtoClient: ~IMediaPipeline() deactivate GStreamer_client rialtoClient -> rialtoServer: ~IMediaPipeline() rialtoServer -> GStreamer_server: Destroy rialto server pipeline GStreamer_server --> rialtoServer: rialtoServer --> rialtoClient: rialtoClient --> GStreamer_client: GStreamer_client --> Starboard Starboard --> Cobalt: @enduml |
@startuml autonumber box "Container" #LightGreen participant Client participant rialtoClient end box box "Platform" #LightBlue participant rialtoServer participant Ocdm end box alt Client should check if the required key system is supported Client -> rialtoClient: supportsKeySystem(key_system) rialtoClient -> rialtoServer: supportsKeySystem(key_system) rialtoServer -> Ocdm: opencdm_is_type_supported(key_system, "") Ocdm --> rialtoServer: result rialtoServer --> rialtoClient: result rialtoClient --> Client: result else Or find the supported key systems then choose its preferred Client -> rialtoClient: getSupportedKeySystems() rialtoClient -> rialtoServer: getSupportedKeySystems() loop For each key system supported by Rialto rialtoServer -> Ocdm: opencdm_is_type_supported(key_system, "") Ocdm --> rialtoServer: result opt If key_system supported rialtoServer -> rialtoServer: Add key_system to array of supported keys systems end end rialtoServer --> rialtoClient: key_systems rialtoClient --> Client: key_systems end @enduml |
@startuml
autonumber
box "Container" #LightGreen
participant Netflix
participant DPI
participant rialtoClient
end box
box "Platform" #LightBlue
participant rialtoServer
participant Ocdm
end box
Netflix -> DPI: getDrmVersion()
DPI -> rialtoClient: getSupportedKeySystemVersion("com.netflix.playready")
rialtoClient -> rialtoServer: getSupportedKeySystemVersion(key_system)
rialtoServer -> Ocdm: opencdm_create_system(key_system);
note right: This temporary media keys does not count towards\nany quota allocated by Rialto Server Manager
Ocdm --> rialtoServer: media_keys
rialtoServer -> Ocdm: opencdm_system_get_version(media_keys)
Ocdm --> rialtoServer: version
rialtoServer -> Ocdm: opencdm_destruct_system(media_keys)
Ocdm --> rialtoServer: status
opt Key system version retrieved successfully
rialtoServer --> rialtoClient: rv=true, version
else Error querying supported key system version
rialtoServer --> rialtoClient: rv=false, version=""
end
rialtoClient --> DPI: rv, version
DPI --> Netflix: rv, version
@enduml |
@startuml autonumber box "Container" #LightGreen participant Cobalt participant Starboard participant ocdmProxy participant rialtoClient end box box "Platform" #LightBlue participant rialtoServer participant Ocdm end box Cobalt -> Starboard: SbDrmCreateSystem(key_system) Starboard -> ocdmProxy: opencdm_create_system(key_system) ocdmProxy -> rialtoClient: createMediaKeys(key_system) rialtoClient -> rialtoServer: createMediaKeys(key_system) rialtoServer -> Ocdm: opencdm_create_system(key_system) Ocdm --> rialtoServer: handle rialtoServer -> rialtoServer: Store Media Keys instance handle note right This stored handle is only needed for deleting any MediaKeys objects that the client fails to destroy when moved out of the Running state. end note rialtoServer --> rialtoClient: media_keys_handle rialtoClient --> ocdmProxy: media_keys_handle ocdmProxy --> Starboard: handle Starboard --> Cobalt: handle @enduml |
@startuml
autonumber
box "Container" #LightGreen
participant Netflix
participant DPI
participant rialtoClient
end box
box "Platform" #LightBlue
participant rialtoServer
participant Ocdm
end box
Netflix -> DPI: initialize(drmSystemCallback, provisioningEngine)
DPI -> rialtoClient: createMediaKeys("com.netflix.playready")
rialtoClient -> rialtoServer: createMediaKeys(key_system)
rialtoServer -> Ocdm: opencdm_create_system(key_system)
Ocdm --> rialtoServer: handle
rialtoServer -> rialtoServer: Store Media Keys instance handle
note right
This stored handle is only needed for deleting any
MediaKeys objects that the client fails to destroy
when moved out of the Running state.
end note
rialtoServer --> rialtoClient: media_keys_handle
rialtoClient --> DPI: media_keys_handle
DPI --> Netflix: status
@enduml |
@startuml autonumber box "Container" #LightGreen participant Cobalt participant Starboard participant ocdmProxy participant rialtoClient end box box "Platform" #LightBlue participant rialtoServer participant Ocdm end box Cobalt -> Starboard: SbDrmDestroySystem(handle) Starboard -> ocdmProxy: opencdm_destruct_system(handle) ocdmProxy -> rialtoClient: ~IMediaKeys() rialtoClient -> rialtoServer: destroyMediaKeys(media_keys_handle) rialtoServer -> Ocdm: opencdm_destruct_system(handle) Ocdm --> rialtoServer: status rialtoServer -> rialtoServer: Remove stored MediaKeys handle rialtoServer --> rialtoClient: status rialtoClient --> ocdmProxy: status ocdmProxy --> Starboard: status Starboard --> Cobalt: status @enduml |
@startuml autonumber box "Container" #LightGreen participant Netflix participant DPI participant rialtoClient end box box "Platform" #LightBlue participant rialtoServer participant Ocdm end box Netflix -> DPI: teardown() DPI -> rialtoClient: ~IMediaKeys() rialtoClient -> rialtoServer: destroyMediaKeys(media_keys_handle) rialtoServer -> Ocdm: opencdm_destruct_system(handle) Ocdm --> rialtoServer: status rialtoServer -> rialtoServer: Remove stored MediaKeys handle rialtoServer --> rialtoClient: status rialtoClient --> DPI: status DPI --> Netflix: status note over Netflix: To prevent leaks ~IDrmSystem() should call\n~IMediaKeys() if teardown() wasn't called @enduml |
@startuml autonumber box "Container" #LightGreen participant Client participant rialtoClient end box box "Platform" #LightBlue participant rialtoServer participant Ocdm end box Client -> rialtoClient: isServerCertificateSupported(key_system) rialtoClient -> rialtoServer: isServerCertificateSupported(key_system) rialtoServer -> Ocdm: opencdm_system_supports_server_certificate(key_system) Ocdm --> rialtoServer: result rialtoServer --> rialtoClient: result rialtoClient --> Client: result @enduml |
There doesn't seem to be any obvious trigger for initialising Rialto in Cobalt/Gst environment so do so on first API call that needs to use Rialto.
@startuml autonumber box "Container" #LightGreen participant Starboard participant ocdmProxy participant GStreamer_client participant rialtoClient end box alt EME requires Rialto first Starboard -> ocdmProxy: Any API that requires Rialto call opt if !rialtoInitialised ocdmProxy -> rialtoClient: init() end ocdmProxy -> rialtoClient: API call else MSE requires Rialto first Starboard -> GStreamer_client: Any API that requires Rialto call opt if !rialtoInitialised GStreamer_client -> rialtoClient: init() end GStreamer_client -> rialtoClient: API call end @enduml |
init() API is not currently implemented. Rialto client currently automatically establishes IPC connection automatically during initialisation |
Terminating Rialto has an even less obvious trigger than initialisation, for the purposes of being able to test suggest that when player & CDM count reaches 0 that we terminate - this could possibly be improved by waiting, say, 10 seconds to see if another API call occurs. If app calls another API after termination then Rialto will be re-initialised.
@startuml autonumber box "Container" #LightGreen participant Starboard participant ocdmProxy participant GStreamer_client participant rialtoClient end box Starboard -> GStreamer_client: SbPlayerDestroy() GStreamer_client -> GStreamer_client: num_pipeline_sessions-- opt if (num_media_keys == 0 && num_pipeline_sessions == 0) GStreamer_client -> rialtoClient: term() end opt Starboard -> ocdmProxy: SbDrmDestroySystem() ocdmProxy -> ocdmProxy: num_media_keys-- opt if (num_media_keys == 0 && num_pipeline_sessions == 0) ocdmProxy -> rialtoClient: term() end end @enduml |
term() API is not currently implemented and there is no mechanism to shut down IPC connection other than terminating the process |